mirror of
https://github.com/openharmony/device_soc_goodix.git
synced 2026-07-01 21:54:03 -04:00
!121 升级GR551x_SDK_v2.0.2
Merge pull request !121 from goodix_zhaoxingyu/GR551x_SDK_v202
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2021 GOODIX.
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
|
||||
Executable → Regular
+19
-15
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2021 GOODIX.
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
@@ -11,37 +11,41 @@
|
||||
# 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")
|
||||
|
||||
copy("link-script") {
|
||||
sources = [ "sdk_liteos/platform/startup/gr551x.ld" ]
|
||||
action("resolve-link-script") {
|
||||
script = "//build/lite/run_shell_cmd.py"
|
||||
args = [
|
||||
"${compile_prefix}cpp${toolchain_cmd_suffix}",
|
||||
"-include",
|
||||
rebase_path("sdk_liteos/config/custom_config.h"),
|
||||
"-E",
|
||||
rebase_path("sdk_liteos/platform/linker/gr5515.ld.tmpl"),
|
||||
"-o",
|
||||
rebase_path("$root_build_dir/bin/link.ld"),
|
||||
"-P",
|
||||
]
|
||||
outputs = [ "$root_build_dir/bin/link.ld" ]
|
||||
}
|
||||
|
||||
copy("sdk_lib") {
|
||||
sources =
|
||||
[ "sdk_liteos/gr551x_sdk/components/sdk/linker/lib_gcc/libble_sdk.a" ]
|
||||
sources = [ "sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/libble_sdk.a" ]
|
||||
outputs = [ "$root_build_dir/libs/libble_sdk.a" ]
|
||||
}
|
||||
|
||||
copy("rom_symbol") {
|
||||
sources = [
|
||||
"sdk_liteos/gr551x_sdk/components/patch/symbol_table/rom_symbol_gcc.txt",
|
||||
]
|
||||
sources =
|
||||
[ "sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/rom_symbol_gcc.txt" ]
|
||||
outputs = [ "$root_build_dir/libs/rom_symbol_gcc.txt" ]
|
||||
}
|
||||
|
||||
module_name = get_path_info(rebase_path("."), "name")
|
||||
module_group(module_name) {
|
||||
module_group("gr551x") {
|
||||
deps = [
|
||||
":link-script",
|
||||
":resolve-link-script",
|
||||
":rom_symbol",
|
||||
":sdk_lib",
|
||||
"//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_static",
|
||||
"//build/lite/config/component/cJSON:cjson_static",
|
||||
]
|
||||
|
||||
modules = [
|
||||
"sdk_liteos",
|
||||
"components",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 GOODIX.
|
||||
* Copyright (c) 2024 GOODIX.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
@@ -17,7 +17,8 @@
|
||||
#include "iot_gpio.h"
|
||||
#include "app_io.h"
|
||||
#include "app_gpiote.h"
|
||||
#include "stdbool.h"
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
/* ID 0~31 Normal GPIO */
|
||||
@@ -118,7 +119,7 @@ static int get_pin_index(uint32_t pin)
|
||||
return index;
|
||||
}
|
||||
|
||||
static void app_io_callback(app_gpiote_evt_t *p_evt)
|
||||
static void app_io_callback(app_io_evt_t *p_evt)
|
||||
{
|
||||
uint32_t index = 0;
|
||||
|
||||
@@ -160,7 +161,7 @@ unsigned int IoTGpioSetDir(unsigned int id, IotGpioDir dir)
|
||||
if (dir == IOT_GPIO_DIR_IN) {
|
||||
io_init.mode = APP_IO_MODE_INPUT;
|
||||
} else if (dir == IOT_GPIO_DIR_OUT) {
|
||||
io_init.mode = APP_IO_MODE_OUT_PUT;
|
||||
io_init.mode = APP_IO_MODE_OUTPUT;
|
||||
}
|
||||
|
||||
g_gpio_dir[id] = dir;
|
||||
@@ -244,7 +245,6 @@ unsigned int IoTGpioRegisterIsrFunc(unsigned int id, IotGpioIntType intType, Iot
|
||||
gpiote_param.type = io_type;
|
||||
gpiote_param.pin = pin;
|
||||
gpiote_param.pull = APP_IO_PULLUP;
|
||||
gpiote_param.handle_mode = APP_IO_ENABLE_WAKEUP;
|
||||
if (intType == IOT_INT_TYPE_LEVEL) {
|
||||
if (intPolarity == IOT_GPIO_EDGE_FALL_LEVEL_LOW) {
|
||||
isr_cfg_info[id].mode = APP_IO_MODE_IT_LOW;
|
||||
@@ -293,7 +293,6 @@ unsigned int IoTGpioUnregisterIsrFunc(unsigned int id)
|
||||
gpiote_param.pin = pin;
|
||||
gpiote_param.mode = isr_cfg_info[id].mode;
|
||||
gpiote_param.pull = APP_IO_PULLUP;
|
||||
gpiote_param.handle_mode = APP_IO_ENABLE_WAKEUP;
|
||||
gpiote_param.io_evt_cb = NULL;
|
||||
|
||||
if (isr_cfg_info[id].initialized == false) {
|
||||
@@ -330,7 +329,6 @@ unsigned int IoTGpioSetIsrMode(unsigned int id, IotGpioIntType intType, IotGpioI
|
||||
gpiote_param.type = io_type;
|
||||
gpiote_param.pin = pin;
|
||||
gpiote_param.pull = APP_IO_PULLUP;
|
||||
gpiote_param.handle_mode = APP_IO_ENABLE_WAKEUP;
|
||||
gpiote_param.io_evt_cb = app_io_callback;
|
||||
|
||||
if (intType == IOT_INT_TYPE_LEVEL) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 GOODIX.
|
||||
* Copyright (c) 2024 GOODIX.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
@@ -20,72 +20,100 @@
|
||||
|
||||
/* I2C0 config params */
|
||||
/* SCL : GPIO30 */
|
||||
#define USER_I2C0_SCL_PIN APP_IO_PIN_30
|
||||
#define USER_I2C0_SCL_PIN_TYPE APP_IO_TYPE_NORMAL
|
||||
#define USER_I2C0_SCL_PIN_MUX APP_IO_MUX_2
|
||||
#define USER_I2C0_SCL_PIN_PULL APP_IO_PULLUP
|
||||
#define USER_I2C0_SCL_PIN APP_IO_PIN_30
|
||||
#define USER_I2C0_SCL_PIN_TYPE APP_IO_TYPE_NORMAL
|
||||
#define USER_I2C0_SCL_PIN_MUX APP_IO_MUX_2
|
||||
#define USER_I2C0_SCL_PIN_PULL APP_IO_PULLUP
|
||||
|
||||
/* SDA : GPIO26 */
|
||||
#define USER_I2C0_SDA_PIN APP_IO_PIN_26
|
||||
#define USER_I2C0_SDA_PIN_TYPE APP_IO_TYPE_NORMAL
|
||||
#define USER_I2C0_SDA_PIN_MUX APP_IO_MUX_2
|
||||
#define USER_I2C0_SDA_PIN_PULL APP_IO_PULLUP
|
||||
#define USER_I2C0_SPEED I2C_SPEED_400K
|
||||
#define I2C0_IO_CONFIG {{USER_I2C0_SCL_PIN_TYPE, USER_I2C0_SCL_PIN_MUX, USER_I2C0_SCL_PIN, USER_I2C0_SCL_PIN_PULL}, \
|
||||
{USER_I2C0_SDA_PIN_TYPE, USER_I2C0_SDA_PIN_MUX, USER_I2C0_SDA_PIN, USER_I2C0_SDA_PIN_PULL}}
|
||||
#define I2C0_MODE_CONFIG {APP_I2C_TYPE_INTERRUPT, DMA_Channel0, DMA_Channel0}
|
||||
#define I2C0_I2C_CONFIG {USER_I2C0_SPEED, 0x00, I2C_ADDRESSINGMODE_7BIT, I2C_GENERALCALL_DISABLE}
|
||||
#define I2C0_PARAM_CONFIG {APP_I2C_ID_0, APP_I2C_ROLE_MASTER, I2C0_IO_CONFIG, I2C0_MODE_CONFIG, I2C0_I2C_CONFIG}
|
||||
#define USER_I2C0_SDA_PIN APP_IO_PIN_26
|
||||
#define USER_I2C0_SDA_PIN_TYPE APP_IO_TYPE_NORMAL
|
||||
#define USER_I2C0_SDA_PIN_MUX APP_IO_MUX_2
|
||||
#define USER_I2C0_SDA_PIN_PULL APP_IO_PULLUP
|
||||
#define USER_I2C0_SPEED I2C_SPEED_400K
|
||||
|
||||
#define I2C0_IO_CONFIG \
|
||||
{ \
|
||||
{USER_I2C0_SCL_PIN_TYPE, USER_I2C0_SCL_PIN_MUX, USER_I2C0_SCL_PIN, USER_I2C0_SCL_PIN_PULL}, \
|
||||
{USER_I2C0_SDA_PIN_TYPE, USER_I2C0_SDA_PIN_MUX, USER_I2C0_SDA_PIN, USER_I2C0_SDA_PIN_PULL}, \
|
||||
}
|
||||
|
||||
#define I2C0_DMA_CONFIG \
|
||||
{ \
|
||||
DMA0, DMA0, DMA_Channel2, DMA_Channel3 \
|
||||
}
|
||||
|
||||
#define I2C0_I2C_CONFIG \
|
||||
{ \
|
||||
USER_I2C0_SPEED, 0x00, I2C_ADDRESSINGMODE_7BIT, I2C_GENERALCALL_DISABLE \
|
||||
}
|
||||
|
||||
#define I2C0_PARAM_CONFIG \
|
||||
{ \
|
||||
APP_I2C_ID_0, APP_I2C_ROLE_MASTER, I2C0_IO_CONFIG, I2C0_DMA_CONFIG, I2C0_I2C_CONFIG \
|
||||
}
|
||||
|
||||
/* I2C1 config params */
|
||||
/* SCL : GPIO8 */
|
||||
#define USER_I2C1_SCL_PIN APP_IO_PIN_8
|
||||
#define USER_I2C1_SCL_PIN_TYPE APP_IO_TYPE_NORMAL
|
||||
#define USER_I2C1_SCL_PIN_MUX APP_IO_MUX_1
|
||||
#define USER_I2C1_SCL_PIN_PULL APP_IO_PULLUP
|
||||
#define USER_I2C1_SCL_PIN APP_IO_PIN_8
|
||||
#define USER_I2C1_SCL_PIN_TYPE APP_IO_TYPE_NORMAL
|
||||
#define USER_I2C1_SCL_PIN_MUX APP_IO_MUX_1
|
||||
#define USER_I2C1_SCL_PIN_PULL APP_IO_PULLUP
|
||||
|
||||
/* SDA : GPIO9 */
|
||||
#define USER_I2C1_SDA_PIN APP_IO_PIN_9
|
||||
#define USER_I2C1_SDA_PIN_TYPE APP_IO_TYPE_NORMAL
|
||||
#define USER_I2C1_SDA_PIN_MUX APP_IO_MUX_1
|
||||
#define USER_I2C1_SDA_PIN_PULL APP_IO_PULLUP
|
||||
#define USER_I2C1_SPEED I2C_SPEED_400K
|
||||
#define USER_I2C1_SDA_PIN APP_IO_PIN_9
|
||||
#define USER_I2C1_SDA_PIN_TYPE APP_IO_TYPE_NORMAL
|
||||
#define USER_I2C1_SDA_PIN_MUX APP_IO_MUX_1
|
||||
#define USER_I2C1_SDA_PIN_PULL APP_IO_PULLUP
|
||||
#define USER_I2C1_SPEED I2C_SPEED_400K
|
||||
|
||||
#define I2C1_IO_CONFIG {{USER_I2C1_SCL_PIN_TYPE, USER_I2C1_SCL_PIN_MUX, USER_I2C1_SCL_PIN, USER_I2C1_SCL_PIN_PULL}, \
|
||||
{USER_I2C1_SDA_PIN_TYPE, USER_I2C1_SDA_PIN_MUX, USER_I2C1_SDA_PIN, USER_I2C1_SDA_PIN_PULL}}
|
||||
#define I2C1_MODE_CONFIG {APP_I2C_TYPE_INTERRUPT, DMA_Channel0, DMA_Channel0}
|
||||
#define I2C1_I2C_CONFIG {USER_I2C1_SPEED, 0x00, I2C_ADDRESSINGMODE_7BIT, I2C_GENERALCALL_DISABLE}
|
||||
#define I2C1_PARAM_CONFIG {APP_I2C_ID_1, APP_I2C_ROLE_MASTER, I2C1_IO_CONFIG, I2C1_MODE_CONFIG, I2C1_I2C_CONFIG}
|
||||
#define I2C_SYNC_TIMEOUT 20
|
||||
#define I2C1_IO_CONFIG \
|
||||
{ \
|
||||
{USER_I2C1_SCL_PIN_TYPE, USER_I2C1_SCL_PIN_MUX, USER_I2C1_SCL_PIN, USER_I2C1_SCL_PIN_PULL}, \
|
||||
{USER_I2C1_SDA_PIN_TYPE, USER_I2C1_SDA_PIN_MUX, USER_I2C1_SDA_PIN, USER_I2C1_SDA_PIN_PULL}, \
|
||||
}
|
||||
|
||||
#define I2C_BAUDRATE_100K 100
|
||||
#define I2C_BAUDRATE_400K 400
|
||||
#define I2C_BAUDRATE_1000K 1000
|
||||
#define I2C_BAUDRATE_2000K 2000
|
||||
#define I2C2_DMA_CONFIG \
|
||||
{ \
|
||||
DMA0, DMA_Channel4, DMA_Channel5 \
|
||||
}
|
||||
|
||||
static const app_i2c_params_t i2c_cfg_params[APP_I2C_ID_MAX] = {
|
||||
I2C0_PARAM_CONFIG,
|
||||
I2C1_PARAM_CONFIG
|
||||
};
|
||||
static uint32_t i2c_tx_mutex[APP_I2C_ID_MAX];
|
||||
static uint32_t i2c_rx_mutex[APP_I2C_ID_MAX];
|
||||
#define I2C1_I2C_CONFIG \
|
||||
{ \
|
||||
USER_I2C1_SPEED, 0x00, I2C_ADDRESSINGMODE_7BIT, I2C_GENERALCALL_DISABLE \
|
||||
}
|
||||
|
||||
#define I2C1_PARAM_CONFIG \
|
||||
{ \
|
||||
APP_I2C_ID_1, APP_I2C_ROLE_MASTER, I2C1_IO_CONFIG, I2C2_DMA_CONFIG, I2C1_I2C_CONFIG \
|
||||
}
|
||||
|
||||
#define I2C_SYNC_TIMEOUT 20
|
||||
|
||||
#define I2C_BAUDRATE_100K 100
|
||||
#define I2C_BAUDRATE_400K 400
|
||||
#define I2C_BAUDRATE_1000K 1000
|
||||
#define I2C_BAUDRATE_2000K 2000
|
||||
|
||||
static app_i2c_params_t s_i2c_params[APP_I2C_ID_MAX] = {I2C0_PARAM_CONFIG, I2C1_PARAM_CONFIG};
|
||||
static uint32_t s_i2c_tx_mutex[APP_I2C_ID_MAX];
|
||||
static uint32_t s_i2c_rx_mutex[APP_I2C_ID_MAX];
|
||||
|
||||
unsigned int IoTI2cWrite(unsigned int id, unsigned short deviceAddr, const unsigned char *data, unsigned int dataLen)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (id > APP_I2C_ID_MAX) {
|
||||
if (id >= APP_I2C_ID_MAX) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
LOS_MuxPend(i2c_tx_mutex[id], LOS_WAIT_FOREVER);
|
||||
LOS_MuxPend(s_i2c_tx_mutex[id], LOS_WAIT_FOREVER);
|
||||
ret = app_i2c_transmit_sync(id, deviceAddr, data, dataLen, I2C_SYNC_TIMEOUT);
|
||||
if (ret != 0) {
|
||||
printf("ret=%d\r\n", ret);
|
||||
LOS_MuxPost(i2c_tx_mutex[id]);
|
||||
LOS_MuxPost(s_i2c_tx_mutex[id]);
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
LOS_MuxPost(i2c_tx_mutex[id]);
|
||||
LOS_MuxPost(s_i2c_tx_mutex[id]);
|
||||
|
||||
return IOT_SUCCESS;
|
||||
}
|
||||
@@ -94,13 +122,13 @@ unsigned int IoTI2cRead(unsigned int id, unsigned short deviceAddr, unsigned cha
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
LOS_MuxPend(i2c_rx_mutex[id], LOS_WAIT_FOREVER);
|
||||
LOS_MuxPend(s_i2c_rx_mutex[id], LOS_WAIT_FOREVER);
|
||||
ret = app_i2c_receive_sync(id, deviceAddr, data, dataLen, I2C_SYNC_TIMEOUT);
|
||||
if (ret != 0) {
|
||||
LOS_MuxPost(i2c_rx_mutex[id]);
|
||||
LOS_MuxPost(s_i2c_rx_mutex[id]);
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
LOS_MuxPost(i2c_rx_mutex[id]);
|
||||
LOS_MuxPost(s_i2c_rx_mutex[id]);
|
||||
|
||||
return IOT_SUCCESS;
|
||||
}
|
||||
@@ -108,39 +136,37 @@ unsigned int IoTI2cRead(unsigned int id, unsigned short deviceAddr, unsigned cha
|
||||
unsigned int IoTI2cInit(unsigned int id, unsigned int baudrate)
|
||||
{
|
||||
int ret = 0;
|
||||
app_i2c_params_t i2c_params;
|
||||
uint32_t uwRet;
|
||||
|
||||
if (id > APP_I2C_ID_MAX) {
|
||||
if (id >= APP_I2C_ID_MAX) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
memcpy_s(&i2c_params, sizeof(app_i2c_params_t), &i2c_cfg_params[id], sizeof(app_i2c_params_t));
|
||||
if (baudrate == I2C_BAUDRATE_100K) {
|
||||
i2c_params.init.speed = I2C_SPEED_100K;
|
||||
s_i2c_params[id].init.speed = I2C_SPEED_100K;
|
||||
} else if (baudrate == I2C_BAUDRATE_400K) {
|
||||
i2c_params.init.speed = I2C_SPEED_400K;
|
||||
} else if (baudrate == I2C_BAUDRATE_1000K) {
|
||||
i2c_params.init.speed = I2C_SPEED_1000K;
|
||||
s_i2c_params[id].init.speed = I2C_SPEED_400K;
|
||||
} else if (baudrate == I2C_BAUDRATE_1000K) {
|
||||
s_i2c_params[id].init.speed = I2C_SPEED_1000K;
|
||||
} else if (baudrate == I2C_BAUDRATE_2000K) {
|
||||
i2c_params.init.speed = I2C_SPEED_2000K;
|
||||
s_i2c_params[id].init.speed = I2C_SPEED_2000K;
|
||||
} else {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
ret = app_i2c_init(&i2c_params, NULL);
|
||||
ret = app_i2c_init(&s_i2c_params[id], NULL);
|
||||
if (ret != 0) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
uwRet = LOS_MuxCreate(&i2c_tx_mutex[id]);
|
||||
uwRet = LOS_MuxCreate(&s_i2c_tx_mutex[id]);
|
||||
if (uwRet != LOS_OK) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
uwRet = LOS_MuxCreate(&i2c_rx_mutex[id]);
|
||||
uwRet = LOS_MuxCreate(&s_i2c_rx_mutex[id]);
|
||||
if (uwRet != LOS_OK) {
|
||||
LOS_SemDelete(i2c_tx_mutex[id]);
|
||||
LOS_SemDelete(s_i2c_tx_mutex[id]);
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -149,13 +175,13 @@ unsigned int IoTI2cInit(unsigned int id, unsigned int baudrate)
|
||||
|
||||
unsigned int IoTI2cDeinit(unsigned int id)
|
||||
{
|
||||
if (id > APP_I2C_ID_MAX) {
|
||||
if (id >= APP_I2C_ID_MAX) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
app_i2c_deinit(id);
|
||||
LOS_SemDelete(i2c_tx_mutex[id]);
|
||||
LOS_SemDelete(i2c_rx_mutex[id]);
|
||||
LOS_SemDelete(s_i2c_tx_mutex[id]);
|
||||
LOS_SemDelete(s_i2c_rx_mutex[id]);
|
||||
|
||||
return IOT_SUCCESS;
|
||||
}
|
||||
@@ -163,27 +189,25 @@ unsigned int IoTI2cDeinit(unsigned int id)
|
||||
unsigned int IoTI2cSetBaudrate(unsigned int id, unsigned int baudrate)
|
||||
{
|
||||
int ret = 0;
|
||||
app_i2c_params_t i2c_params;
|
||||
|
||||
if (id > APP_I2C_ID_MAX) {
|
||||
if (id >= APP_I2C_ID_MAX) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
memcpy_s(&i2c_params, sizeof(app_i2c_params_t), &i2c_cfg_params[id], sizeof(app_i2c_params_t));
|
||||
if (baudrate == I2C_BAUDRATE_100K) {
|
||||
i2c_params.init.speed = I2C_SPEED_100K;
|
||||
s_i2c_params[id].init.speed = I2C_SPEED_100K;
|
||||
} else if (baudrate == I2C_BAUDRATE_400K) {
|
||||
i2c_params.init.speed = I2C_SPEED_400K;
|
||||
} else if (baudrate == I2C_BAUDRATE_1000K) {
|
||||
i2c_params.init.speed = I2C_SPEED_1000K;
|
||||
s_i2c_params[id].init.speed = I2C_SPEED_400K;
|
||||
} else if (baudrate == I2C_BAUDRATE_1000K) {
|
||||
s_i2c_params[id].init.speed = I2C_SPEED_1000K;
|
||||
} else if (baudrate == I2C_BAUDRATE_2000K) {
|
||||
i2c_params.init.speed = I2C_SPEED_2000K;
|
||||
s_i2c_params[id].init.speed = I2C_SPEED_2000K;
|
||||
} else {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
app_i2c_deinit(id);
|
||||
ret = app_i2c_init(&i2c_params, NULL);
|
||||
ret = app_i2c_init(&s_i2c_params[id], NULL);
|
||||
if (ret != 0) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 GOODIX.
|
||||
* Copyright (c) 2024 GOODIX.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
@@ -17,28 +17,110 @@
|
||||
#include "iot_pwm.h"
|
||||
#include "app_pwm.h"
|
||||
|
||||
#define PWM_IO_CONFIG {{ APP_IO_TYPE_MSIO, APP_IO_MUX_0, APP_IO_PIN_0, APP_IO_NOPULL, APP_PWM_PIN_ENABLE }, \
|
||||
{ APP_IO_TYPE_MSIO, APP_IO_MUX_0, APP_IO_PIN_1, APP_IO_NOPULL, APP_PWM_PIN_ENABLE }, \
|
||||
{ APP_IO_TYPE_MSIO, APP_IO_MUX_0, APP_IO_PIN_2, APP_IO_NOPULL, APP_PWM_PIN_ENABLE }}
|
||||
// APP_PWM_ID_0
|
||||
#define USER_PWM0_CHANNEL_A_PIN APP_IO_PIN_0
|
||||
#define USER_PWM0_CHANNEL_A_PIN_TYPE APP_IO_TYPE_MSIO
|
||||
#define USER_PWM0_CHANNEL_A_PIN_MUX APP_IO_MUX_0
|
||||
#define USER_PWM0_CHANNEL_A_PIN_PULL APP_IO_NOPULL
|
||||
|
||||
#define PWM_ACTIVE_CAHN APP_PWM_ACTIVE_CHANNEL_ALL
|
||||
#define PWM_CONFIG { PWM_MODE_FLICKER, PWM_ALIGNED_EDGE, 10, 500, 200, \
|
||||
{ 50, PWM_DRIVEPOLARITY_POSITIVE }, \
|
||||
{ 50, PWM_DRIVEPOLARITY_POSITIVE }, \
|
||||
{ 50, PWM_DRIVEPOLARITY_POSITIVE }}
|
||||
#define PWM_PARAM_CONFIG {0, PWM_IO_CONFIG, PWM_ACTIVE_CAHN, PWM_CONFIG }
|
||||
#define USER_PWM0_CHANNEL_B_PIN APP_IO_PIN_1
|
||||
#define USER_PWM0_CHANNEL_B_PIN_TYPE APP_IO_TYPE_MSIO
|
||||
#define USER_PWM0_CHANNEL_B_PIN_MUX APP_IO_MUX_0
|
||||
#define USER_PWM0_CHANNEL_B_PIN_PULL APP_IO_NOPULL
|
||||
|
||||
#define USER_PWM0_CHANNEL_C_PIN APP_IO_PIN_2
|
||||
#define USER_PWM0_CHANNEL_C_PIN_TYPE APP_IO_TYPE_MSIO
|
||||
#define USER_PWM0_CHANNEL_C_PIN_MUX APP_IO_MUX_0
|
||||
#define USER_PWM0_CHANNEL_C_PIN_PULL APP_IO_NOPULL
|
||||
|
||||
#define PWM0_IO_CONFIG \
|
||||
{ \
|
||||
{USER_PWM0_CHANNEL_A_PIN_TYPE, USER_PWM0_CHANNEL_A_PIN_MUX, USER_PWM0_CHANNEL_A_PIN, USER_PWM0_CHANNEL_A_PIN_PULL, APP_PWM_PIN_ENABLE}, \
|
||||
{USER_PWM0_CHANNEL_B_PIN_TYPE, USER_PWM0_CHANNEL_B_PIN_MUX, USER_PWM0_CHANNEL_B_PIN, USER_PWM0_CHANNEL_B_PIN_PULL, APP_PWM_PIN_ENABLE}, \
|
||||
{USER_PWM0_CHANNEL_C_PIN_TYPE, USER_PWM0_CHANNEL_C_PIN_MUX, USER_PWM0_CHANNEL_C_PIN, USER_PWM0_CHANNEL_C_PIN_PULL, APP_PWM_PIN_ENABLE}, \
|
||||
}
|
||||
|
||||
#define PWM0_ACTIVE_CHANNEL APP_PWM_ACTIVE_CHANNEL_ALL
|
||||
|
||||
#define PWM0_PWM_CHANNEL_A_CONFIG \
|
||||
{ \
|
||||
50, PWM_DRIVEPOLARITY_POSITIVE \
|
||||
}
|
||||
|
||||
#define PWM0_PWM_CHANNEL_B_CONFIG \
|
||||
{ \
|
||||
50, PWM_DRIVEPOLARITY_POSITIVE \
|
||||
}
|
||||
|
||||
#define PWM0_PWM_CHANNEL_C_CONFIG \
|
||||
{ \
|
||||
50, PWM_DRIVEPOLARITY_POSITIVE \
|
||||
}
|
||||
|
||||
#define PWM0_PWM_CONFIG \
|
||||
{ \
|
||||
PWM_MODE_FLICKER, PWM_ALIGNED_EDGE, 10, 500, 200, PWM0_PWM_CHANNEL_A_CONFIG, PWM0_PWM_CHANNEL_B_CONFIG, PWM0_PWM_CHANNEL_C_CONFIG, \
|
||||
}
|
||||
|
||||
#define PWM0_PARAM_CONFIG \
|
||||
{ \
|
||||
APP_PWM_ID_0, PWM0_IO_CONFIG, PWM0_ACTIVE_CHANNEL, PWM0_PWM_CONFIG \
|
||||
}
|
||||
|
||||
// APP_PWM_ID_1
|
||||
#define USER_PWM1_CHANNEL_A_PIN APP_IO_PIN_3
|
||||
#define USER_PWM1_CHANNEL_A_PIN_TYPE APP_IO_TYPE_MSIO
|
||||
#define USER_PWM1_CHANNEL_A_PIN_MUX APP_IO_MUX_0
|
||||
#define USER_PWM1_CHANNEL_A_PIN_PULL APP_IO_NOPULL
|
||||
|
||||
#define USER_PWM1_CHANNEL_B_PIN APP_IO_PIN_4
|
||||
#define USER_PWM1_CHANNEL_B_PIN_TYPE APP_IO_TYPE_MSIO
|
||||
#define USER_PWM1_CHANNEL_B_PIN_MUX APP_IO_MUX_0
|
||||
#define USER_PWM1_CHANNEL_B_PIN_PULL APP_IO_NOPULL
|
||||
|
||||
#define PWM1_IO_CONFIG \
|
||||
{ \
|
||||
{USER_PWM1_CHANNEL_A_PIN_TYPE, USER_PWM1_CHANNEL_A_PIN_MUX, USER_PWM1_CHANNEL_A_PIN, USER_PWM1_CHANNEL_A_PIN_PULL, APP_PWM_PIN_ENABLE}, \
|
||||
{USER_PWM1_CHANNEL_B_PIN_TYPE, USER_PWM1_CHANNEL_B_PIN_MUX, USER_PWM1_CHANNEL_B_PIN, USER_PWM1_CHANNEL_B_PIN_PULL, APP_PWM_PIN_ENABLE}, \
|
||||
{0}, \
|
||||
}
|
||||
|
||||
#define PWM1_ACTIVE_CHANNEL (APP_PWM_ACTIVE_CHANNEL_A | APP_PWM_ACTIVE_CHANNEL_B)
|
||||
|
||||
#define PWM1_PWM_CHANNEL_A_CONFIG \
|
||||
{ \
|
||||
50, PWM_DRIVEPOLARITY_POSITIVE \
|
||||
}
|
||||
|
||||
#define PWM1_PWM_CHANNEL_B_CONFIG \
|
||||
{ \
|
||||
50, PWM_DRIVEPOLARITY_POSITIVE \
|
||||
}
|
||||
|
||||
#define PWM1_PWM_CONFIG \
|
||||
{ \
|
||||
PWM_MODE_FLICKER, PWM_ALIGNED_EDGE, 10, 500, 200, PWM1_PWM_CHANNEL_A_CONFIG, PWM1_PWM_CHANNEL_B_CONFIG, {0}, \
|
||||
}
|
||||
|
||||
#define PWM1_PARAM_CONFIG \
|
||||
{ \
|
||||
APP_PWM_ID_1, PWM1_IO_CONFIG, PWM1_ACTIVE_CHANNEL, PWM1_PWM_CONFIG \
|
||||
}
|
||||
|
||||
static app_pwm_params_t s_pwm_params[APP_PWM_ID_MAX] = {
|
||||
PWM0_PARAM_CONFIG,
|
||||
PWM1_PARAM_CONFIG,
|
||||
};
|
||||
|
||||
unsigned int IoTPwmInit(unsigned int port)
|
||||
{
|
||||
uint16_t ret = APP_DRV_SUCCESS;
|
||||
app_pwm_params_t pwm_params = PWM_PARAM_CONFIG;
|
||||
|
||||
if (port > APP_PWM_ID_MAX) {
|
||||
if (port >= APP_PWM_ID_MAX) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
pwm_params.id = port;
|
||||
ret = app_pwm_init(&pwm_params);
|
||||
ret = app_pwm_init(&s_pwm_params[port]);
|
||||
if (ret != APP_DRV_SUCCESS) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
@@ -49,7 +131,7 @@ unsigned int IoTPwmDeinit(unsigned int port)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (port > APP_PWM_ID_MAX) {
|
||||
if (port >= APP_PWM_ID_MAX) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -63,10 +145,9 @@ unsigned int IoTPwmDeinit(unsigned int port)
|
||||
|
||||
unsigned int IoTPwmStart(unsigned int port, unsigned short duty, unsigned int freq)
|
||||
{
|
||||
app_pwm_params_t pwm_params = PWM_PARAM_CONFIG;
|
||||
app_pwm_channel_init_t channel_cfg = {0};
|
||||
|
||||
if (port > APP_PWM_ID_MAX) {
|
||||
if (port >= APP_PWM_ID_MAX) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -81,7 +162,7 @@ unsigned int IoTPwmStart(unsigned int port, unsigned short duty, unsigned int fr
|
||||
|
||||
unsigned int IoTPwmStop(unsigned int port)
|
||||
{
|
||||
if (port > APP_PWM_ID_MAX) {
|
||||
if (port >= APP_PWM_ID_MAX) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 GOODIX.
|
||||
* Copyright (c) 2024 GOODIX.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "iot_errno.h"
|
||||
#include "iot_uart.h"
|
||||
#include "app_uart.h"
|
||||
#include "app_uart_dma.h"
|
||||
#include "app_io.h"
|
||||
#include "los_sem.h"
|
||||
|
||||
@@ -43,8 +44,9 @@ static app_uart_params_t uart_param[APP_UART_ID_MAX] = {
|
||||
.pull = APP_IO_PULLUP,
|
||||
}
|
||||
},
|
||||
.use_mode = {
|
||||
.type = APP_UART_TYPE_DMA,
|
||||
.dma_cfg = {
|
||||
.tx_dma_instance = DMA0,
|
||||
.rx_dma_instance = DMA0,
|
||||
.tx_dma_channel = DMA_Channel0,
|
||||
.rx_dma_channel = DMA_Channel1,
|
||||
}
|
||||
@@ -67,9 +69,6 @@ static app_uart_params_t uart_param[APP_UART_ID_MAX] = {
|
||||
.pull = APP_IO_PULLUP,
|
||||
}
|
||||
},
|
||||
.use_mode = {
|
||||
.type = APP_UART_TYPE_INTERRUPT, /* UART1 only supports interrupt mode */
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -78,7 +77,7 @@ static uint32_t uart_tx_mutex[APP_UART_ID_MAX];
|
||||
static uint32_t uart_rx_mutex[APP_UART_ID_MAX];
|
||||
static uint32_t g_rx_num[APP_UART_ID_MAX];
|
||||
|
||||
static const app_uart_evt_handler_t *evt_handler[APP_UART_ID_MAX] = {
|
||||
static const app_uart_evt_handler_t evt_handler[APP_UART_ID_MAX] = {
|
||||
app_uart0_callback,
|
||||
app_uart1_callback
|
||||
};
|
||||
@@ -105,6 +104,10 @@ static void app_uart1_callback(app_uart_evt_t *p_evt)
|
||||
|
||||
struct app_uart_params_t* uart_cfg(unsigned int id, const IotUartAttribute *param)
|
||||
{
|
||||
if (id >= APP_UART_ID_MAX) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
app_uart_params_t *params = &uart_param[id];
|
||||
params->init.baud_rate = param->baudRate;
|
||||
params->init.rx_timeout_mode = UART_RECEIVER_TIMEOUT_ENABLE;
|
||||
@@ -159,6 +162,7 @@ unsigned int IoTUartInit(unsigned int id, const IotUartAttribute *param)
|
||||
if (id >= APP_UART_ID_MAX) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
params = uart_cfg(id, param);
|
||||
|
||||
ret = app_uart_init(params, evt_handler[id], &uart_buffer);
|
||||
@@ -166,6 +170,14 @@ unsigned int IoTUartInit(unsigned int id, const IotUartAttribute *param)
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
if (id == APP_UART_ID_0) {
|
||||
// Only UART0 support DMA
|
||||
ret = app_uart_dma_init(params);
|
||||
if (ret != 0) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
uwRet = LOS_BinarySemCreate(0, &uart_rx_sem[id]);
|
||||
if (uwRet != LOS_OK) {
|
||||
return IOT_FAILURE;
|
||||
@@ -192,11 +204,19 @@ int IoTUartRead(unsigned int id, unsigned char *data, unsigned int dataLen)
|
||||
int ret = 0;
|
||||
uint32_t uwRet = 0;
|
||||
|
||||
if (id >= APP_UART_ID_MAX) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
LOS_MuxPend(uart_rx_mutex[id], LOS_WAIT_FOREVER);
|
||||
|
||||
g_rx_num[id] = 0;
|
||||
LOS_SemPend(uart_rx_sem[id], 0);
|
||||
ret = app_uart_receive_async(id, data, dataLen);
|
||||
if (id == APP_UART_ID_0) {
|
||||
ret = app_uart_dma_receive_async(id, data, dataLen);
|
||||
} else {
|
||||
ret = app_uart_receive_async(id, data, dataLen);
|
||||
}
|
||||
if (ret != 0) {
|
||||
LOS_MuxPost(uart_rx_mutex[id]);
|
||||
return IOT_FAILURE;
|
||||
@@ -217,6 +237,10 @@ int IoTUartWrite(unsigned int id, const unsigned char *data, unsigned int dataLe
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (id >= APP_UART_ID_MAX) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
LOS_MuxPend(uart_tx_mutex[id], LOS_WAIT_FOREVER);
|
||||
ret = app_uart_transmit_sync(id, data, dataLen, UART_TIMEOUT);
|
||||
if (ret != 0) {
|
||||
@@ -230,6 +254,10 @@ int IoTUartWrite(unsigned int id, const unsigned char *data, unsigned int dataLe
|
||||
|
||||
unsigned int IoTUartDeinit(unsigned int id)
|
||||
{
|
||||
if (id >= APP_UART_ID_MAX) {
|
||||
return IOT_FAILURE;
|
||||
}
|
||||
|
||||
app_uart_deinit(id);
|
||||
LOS_SemDelete(uart_rx_sem[id]);
|
||||
LOS_SemDelete(uart_tx_mutex[id]);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2021 GOODIX.
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
@@ -19,6 +19,4 @@ config("public") {
|
||||
|
||||
hdf_driver("fs_adapter") {
|
||||
sources = [ "fs_init.c" ]
|
||||
|
||||
deps = [ "//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_static" ]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
template("gr551x_executable") {
|
||||
executable("${target_name}.elf") {
|
||||
forward_variables_from(invoker,
|
||||
"*",
|
||||
[
|
||||
"force_link_libs",
|
||||
"gen_asm",
|
||||
])
|
||||
|
||||
if (defined(ldflags)) {
|
||||
ldflags += [ "-Wl,--whole-archive" ]
|
||||
} else {
|
||||
ldflags = [ "-Wl,--whole-archive" ]
|
||||
}
|
||||
foreach(force_link_lib, invoker.force_link_libs) {
|
||||
ldflags += [ "-l${force_link_lib}" ]
|
||||
}
|
||||
ldflags += [ "-Wl,--no-whole-archive" ]
|
||||
}
|
||||
|
||||
action("${target_name}.bin") {
|
||||
script = "//build/lite/run_shell_cmd.py"
|
||||
args = [
|
||||
"${compile_prefix}objcopy${toolchain_cmd_suffix}",
|
||||
"-O",
|
||||
"binary",
|
||||
rebase_path("${root_build_dir}/bin/${invoker.target_name}.elf"),
|
||||
rebase_path("${root_build_dir}/bin/${invoker.target_name}.bin"),
|
||||
]
|
||||
outputs = [ "${root_build_dir}/bin/${invoker.target_name}.bin" ]
|
||||
deps = [ ":${invoker.target_name}.elf" ]
|
||||
}
|
||||
|
||||
action("${target_name}.hex") {
|
||||
script = "//build/lite/run_shell_cmd.py"
|
||||
args = [
|
||||
"${compile_prefix}objcopy${toolchain_cmd_suffix}",
|
||||
"-O",
|
||||
"ihex",
|
||||
rebase_path("${root_build_dir}/bin/${invoker.target_name}.elf"),
|
||||
rebase_path("${root_build_dir}/bin/${invoker.target_name}.hex"),
|
||||
]
|
||||
outputs = [ "${root_build_dir}/bin/${invoker.target_name}.hex" ]
|
||||
deps = [ ":${invoker.target_name}.elf" ]
|
||||
}
|
||||
|
||||
if (defined(invoker.gen_asm) && invoker.gen_asm) {
|
||||
action("${target_name}.asm") {
|
||||
script = "//build/lite/run_shell_cmd.py"
|
||||
args = [
|
||||
"${compile_prefix}objdump${toolchain_cmd_suffix}",
|
||||
"-D",
|
||||
rebase_path(
|
||||
"${root_build_dir}/unstripped/bin/${invoker.target_name}.elf"),
|
||||
">",
|
||||
rebase_path("${root_build_dir}/bin/${invoker.target_name}.asm"),
|
||||
]
|
||||
outputs = [ "${root_build_dir}/bin/${invoker.target_name}.asm" ]
|
||||
deps = [ ":${invoker.target_name}.elf" ]
|
||||
}
|
||||
}
|
||||
|
||||
group("${target_name}") {
|
||||
deps = [
|
||||
":${target_name}.bin",
|
||||
":${target_name}.hex",
|
||||
]
|
||||
|
||||
if (defined(invoker.gen_asm) && invoker.gen_asm) {
|
||||
deps += [ ":${target_name}.asm" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ root {
|
||||
configNum = 1;
|
||||
gpioIndex = [0];
|
||||
pull = [0];
|
||||
handleMode = [0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Executable → Regular
+5
-5
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2021 GOODIX.
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
@@ -13,12 +13,12 @@
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
module_name = get_path_info(rebase_path("."), "name")
|
||||
module_group(module_name) {
|
||||
module_group("sdk_liteos") {
|
||||
modules = [
|
||||
"platform",
|
||||
"config",
|
||||
"gr551x_sdk",
|
||||
"liteos_m",
|
||||
"config",
|
||||
"platform/main",
|
||||
"platform/system",
|
||||
]
|
||||
}
|
||||
|
||||
Executable → Regular
+2
-3
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2021 GOODIX.
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
@@ -17,6 +17,5 @@ config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
module_name = get_path_info(rebase_path("."), "name")
|
||||
kernel_module(module_name) {
|
||||
kernel_module("config") {
|
||||
}
|
||||
|
||||
Executable → Regular
+132
-44
@@ -47,48 +47,74 @@
|
||||
// <h> Basic configuration
|
||||
|
||||
// <o> Chip version
|
||||
#define GR5515_D
|
||||
#define SOC_GR5515
|
||||
|
||||
// <o> Select chip type
|
||||
// <0=> GR5515
|
||||
// <1=> GR5513
|
||||
// <0=> GR5515IGND
|
||||
// <1=> GR5515IENDU
|
||||
// <2=> GR5515I0ND
|
||||
// <3=> GR5515I0NDA
|
||||
// <4=> GR5515RGBD
|
||||
// <5=> GR5515GGBD
|
||||
// <6=> GR5513BEND
|
||||
// <7=> GR5513BENDU
|
||||
#ifndef CHIP_TYPE
|
||||
#define CHIP_TYPE 0
|
||||
#define CHIP_TYPE 4
|
||||
#endif
|
||||
|
||||
// <o> Platform support sleep function
|
||||
// <0=> not support
|
||||
// <1=> support
|
||||
#ifndef PLAT_SUPPORT_SLEEP
|
||||
#define PLAT_SUPPORT_SLEEP 1
|
||||
#endif
|
||||
|
||||
// <o> Platform support ble function
|
||||
// <0=> not support
|
||||
// <1=> support
|
||||
#ifndef PLAT_SUPPORT_BLE
|
||||
#define PLAT_SUPPORT_BLE 1
|
||||
#endif
|
||||
// <o> Enable encrypt chip
|
||||
// <0=> DISABLE
|
||||
// <1=> ENABLE
|
||||
#ifndef ENCRYPT_ENABLE
|
||||
#define ENCRYPT_ENABLE 1
|
||||
#define ENCRYPT_ENABLE 0
|
||||
#endif
|
||||
|
||||
// <o> Enable the external flash of chip
|
||||
// <0=> DISABLE
|
||||
// <1=> ENABLE
|
||||
#ifndef EXT_EXFLASH_ENABLE
|
||||
#define EXT_EXFLASH_ENABLE 0
|
||||
#define EXT_EXFLASH_ENABLE 0
|
||||
#endif
|
||||
|
||||
// <o> Enable the platform initialization process
|
||||
// <0=> DISABLE
|
||||
// <1=> ENABLE
|
||||
#ifndef PLATFORM_INIT_ENABLE
|
||||
#define PLATFORM_INIT_ENABLE 1
|
||||
#endif
|
||||
|
||||
// <o> Enable system fault trace module
|
||||
// <0=> DISABLE
|
||||
// <1=> ENABLE
|
||||
#ifndef SYS_FAULT_TRACE_ENABLE
|
||||
#define SYS_FAULT_TRACE_ENABLE 1
|
||||
#define SYS_FAULT_TRACE_ENABLE 1
|
||||
#endif
|
||||
|
||||
// <o> Enable APP driver module
|
||||
// <0=> DISABLE
|
||||
// <1=> ENABLE
|
||||
#ifndef APP_DRIVER_USE_ENABLE
|
||||
#define APP_DRIVER_USE_ENABLE 1
|
||||
#define APP_DRIVER_USE_ENABLE 1
|
||||
#endif
|
||||
|
||||
// <o> Eanble APP log module
|
||||
// <0=> DISABLE
|
||||
// <1=> ENABLE
|
||||
#ifndef APP_LOG_ENABLE
|
||||
#define APP_LOG_ENABLE 1
|
||||
#define APP_LOG_ENABLE 1
|
||||
#endif
|
||||
|
||||
// <o> APP log port type
|
||||
@@ -96,22 +122,22 @@
|
||||
// <1=> RTT
|
||||
// <2=> ITM
|
||||
#ifndef APP_LOG_PORT
|
||||
#define APP_LOG_PORT 0
|
||||
#define APP_LOG_PORT 0
|
||||
#endif
|
||||
|
||||
// <o> Eanble APP log store module
|
||||
// <0=> DISABLE
|
||||
// <1=> ENABLE
|
||||
#ifndef APP_LOG_STORE_ENABLE
|
||||
#define APP_LOG_STORE_ENABLE 0
|
||||
#define APP_LOG_STORE_ENABLE 0
|
||||
#endif
|
||||
|
||||
#if (CHIP_TYPE == 0)
|
||||
#if (CHIP_TYPE <= 5)
|
||||
// <o> Enable SK GUI module, only available in GR5515
|
||||
// <0=> DISABLE
|
||||
// <1=> ENABLE
|
||||
#ifndef SK_GUI_ENABLE
|
||||
#define SK_GUI_ENABLE 1
|
||||
#define SK_GUI_ENABLE 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -119,64 +145,78 @@
|
||||
// <0=> DISABLE
|
||||
// <1=> ENABLE
|
||||
#ifndef DEBUG_MONITOR
|
||||
#define DEBUG_MONITOR 0
|
||||
#define DEBUG_MONITOR 0
|
||||
#endif
|
||||
|
||||
// <o> Enable DTM test support
|
||||
// <0=> DISABLE
|
||||
// <1=> ENABLE
|
||||
#ifndef DTM_TEST_ENABLE
|
||||
#define DTM_TEST_ENABLE 0
|
||||
#define DTM_TEST_ENABLE 0
|
||||
#endif
|
||||
|
||||
// <o> Enable BLE DFU support
|
||||
// <0=> DISABLE
|
||||
// <1=> ENABLE
|
||||
#ifndef DFU_ENABLE
|
||||
#define DFU_ENABLE 1
|
||||
#define DFU_ENABLE 1
|
||||
#endif
|
||||
|
||||
// <o> Protection priority level
|
||||
// <i> Default: 0
|
||||
#ifndef FLASH_PROTECT_PRIORITY
|
||||
#define FLASH_PROTECT_PRIORITY 0
|
||||
#define FLASH_PROTECT_PRIORITY 0
|
||||
#endif
|
||||
|
||||
// <o> NVDS Start Address
|
||||
// <i> Default: 0x010FF000
|
||||
#ifndef NVDS_START_ADDR
|
||||
#if (CHIP_TYPE == 1) || (CHIP_TYPE == 6) || (CHIP_TYPE == 7)
|
||||
#define NVDS_START_ADDR 0x0107F000
|
||||
#else
|
||||
#define NVDS_START_ADDR 0x010FF000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// <o> The Number of sectors for NVDS
|
||||
// <i> Default: 1
|
||||
// <i> Range: 1-16
|
||||
#ifndef NVDS_NUM_SECTOR
|
||||
#define NVDS_NUM_SECTOR 1
|
||||
#define NVDS_NUM_SECTOR 1
|
||||
#endif
|
||||
|
||||
// <o> Call Stack Size
|
||||
// <i> Default: 0x4000
|
||||
#ifndef CSTACK_HEAP_SIZE
|
||||
#define CSTACK_HEAP_SIZE 0x4000
|
||||
#ifndef SYSTEM_STACK_SIZE
|
||||
#define SYSTEM_STACK_SIZE 0x4000
|
||||
#endif
|
||||
|
||||
// <o> Call Heap Size
|
||||
// <i> Default: 0x1000
|
||||
#ifndef SYSTEM_HEAP_SIZE
|
||||
#define SYSTEM_HEAP_SIZE 0x1000
|
||||
#endif
|
||||
|
||||
// <o> Enable callstack backtrace function
|
||||
// <i> Default: 0
|
||||
#ifndef ENABLE_BACKTRACE_FEA
|
||||
#define ENABLE_BACKTRACE_FEA 0
|
||||
#define ENABLE_BACKTRACE_FEA 0
|
||||
#endif
|
||||
|
||||
// </h>
|
||||
|
||||
// <h> Boot info configuration
|
||||
// <o> Chip version
|
||||
// <i> Default: 0x00
|
||||
#define CHIP_VER 0x5515
|
||||
|
||||
// <o> Code load address
|
||||
// <i> Default: 0x01002000
|
||||
#define APP_CODE_LOAD_ADDR 0x0100b000
|
||||
#define APP_CODE_LOAD_ADDR 0x01002000
|
||||
|
||||
// <o> Code run address
|
||||
// <i> Default: 0x01002000
|
||||
#define APP_CODE_RUN_ADDR 0x0100b000
|
||||
#define APP_CODE_RUN_ADDR 0x01002000
|
||||
|
||||
// <ol.0..5> System clock
|
||||
// <0=> 64MHZ
|
||||
@@ -194,7 +234,15 @@
|
||||
// <o> Enable internal osc as low power clock
|
||||
// <0=> Default: Disable internal osc as low power clock
|
||||
// <1=> Enable internal osc as low power clock and force CFG_LF_ACCURACY_PPM to 500ppm
|
||||
#define CFG_LPCLK_INTERNAL_EN 0
|
||||
#define CFG_LPCLK_INTERNAL_EN 1
|
||||
|
||||
// <o> Delay time for Crystal stabilization time
|
||||
// <i> Default: 100
|
||||
// <i> Range: 100-500
|
||||
// <i> Note: Set according to actual measurement data
|
||||
#ifndef CFG_CRYSTAL_DELAY
|
||||
#define CFG_CRYSTAL_DELAY 100
|
||||
#endif
|
||||
|
||||
// <o> Delay time for Boot startup
|
||||
// <0=> Not Delay
|
||||
@@ -206,9 +254,6 @@
|
||||
// <1=> Check image
|
||||
#define BOOT_CHECK_IMAGE 1
|
||||
|
||||
// <o> Code version.16bits
|
||||
#define VERSION 1
|
||||
|
||||
// <o> Delay time between flash wakeup and read chip id in warm boot
|
||||
// <i> Default: 0
|
||||
// <i> Range: 0-10
|
||||
@@ -222,53 +267,87 @@
|
||||
#ifndef EXFLASH_WAKEUP_DELAY
|
||||
#define EXFLASH_WAKEUP_DELAY 0
|
||||
#endif
|
||||
|
||||
// </h>
|
||||
|
||||
// <h> BLE resource configuration
|
||||
// <i> Note: The total number of BLE Activities(CONNECTIONS+ADVS+2*PER_ADVS+SYNCS+SCAN) should not exceed the limit 12.
|
||||
// <i> Note: The total number of BLE Activities(CONNECTIONS+ADVS+SCAN) should not exceed the limit 12.
|
||||
|
||||
// <o> Support maximum number of BLE profiles <0-64>
|
||||
// <i> Range: 0-64
|
||||
// <o> Support maximum number of BLE profiles <1-64>
|
||||
// <i> Range: 1-64
|
||||
#ifndef CFG_MAX_PRFS
|
||||
#define CFG_MAX_PRFS 10
|
||||
#define CFG_MAX_PRFS 10
|
||||
#endif
|
||||
|
||||
// <o> Support maximum number of bonded devices <0-10>
|
||||
// <i> Range: 0-10
|
||||
// <o> Support maximum number of bonded devices
|
||||
#ifndef CFG_MAX_BOND_DEVS
|
||||
#define CFG_MAX_BOND_DEVS 4
|
||||
#define CFG_MAX_BOND_DEVS 4
|
||||
#endif
|
||||
|
||||
// <o> Support maximum number of BLE Links <0-10>
|
||||
// <i> Range: 0-10
|
||||
// <o> Config scan duplicate filter list number
|
||||
// <i> Range: 0-50
|
||||
#ifndef CFG_SCAN_DUP_FILT_LIST_NUM
|
||||
#define CFG_SCAN_DUP_FILT_LIST_NUM 10
|
||||
#endif
|
||||
|
||||
// <o> Support maximum number of BLE Links <1-10>
|
||||
// <i> Range: 1-10
|
||||
#ifndef CFG_MAX_CONNECTIONS
|
||||
#define CFG_MAX_CONNECTIONS 10
|
||||
#define CFG_MAX_CONNECTIONS 5
|
||||
#endif
|
||||
|
||||
// <o> Support maximum number of BLE Legacy/Extended Advertisings <0-5>
|
||||
// <i> Range: 0-5
|
||||
// <i> Note: The total number of BLE Legacy/Extended/Periodic Advertisings should not exceed the limit 5.
|
||||
#ifndef CFG_MAX_ADVS
|
||||
#define CFG_MAX_ADVS 1
|
||||
#define CFG_MAX_ADVS 1
|
||||
#endif
|
||||
|
||||
// <o> Support 31 bytes adv data for legacy adv
|
||||
// <0=> NOT SUPPORT
|
||||
// <1=> SUPPORT
|
||||
#ifndef CFG_MAX_ADV_DATA_LEN_SUPPORT
|
||||
#define CFG_MAX_ADV_DATA_LEN_SUPPORT 0
|
||||
#endif
|
||||
|
||||
// <o> Support maximum number of BLE Periodic Advertisings <0-5>
|
||||
// <i> Range: 0-5
|
||||
// <i> Note: The total number of BLE Legacy/Extended/Periodic Advertisings should not exceed the limit 5.
|
||||
#ifndef CFG_MAX_PER_ADVS
|
||||
#define CFG_MAX_PER_ADVS 0
|
||||
#define CFG_MAX_PER_ADVS 0
|
||||
#endif
|
||||
|
||||
// <o> Support maximum number of BLE Periodic Advertising Synchronizations <0-5>
|
||||
// <i> Range: 0-5
|
||||
#ifndef CFG_MAX_SYNCS
|
||||
#define CFG_MAX_SYNCS 0
|
||||
#define CFG_MAX_SYNCS 0
|
||||
#endif
|
||||
|
||||
// <o> Support maximum number of BLE Scan <0-1>
|
||||
// <i> Range: 0-1
|
||||
#ifndef CFG_MAX_SCAN
|
||||
#define CFG_MAX_SCAN 1
|
||||
#define CFG_MAX_SCAN 1
|
||||
#endif
|
||||
|
||||
// <o> support
|
||||
// <0=> NOT SUPPORT
|
||||
// <1=> SUPPORT
|
||||
#ifndef CFG_BT_BREDR
|
||||
#define CFG_BT_BREDR 0
|
||||
#endif
|
||||
|
||||
// <o> Support multiple link with the same device
|
||||
// <0=> NOT SUPPORT
|
||||
// <1=> SUPPORT
|
||||
#ifndef CFG_MUL_LINK_WITH_SAME_DEV
|
||||
#define CFG_MUL_LINK_WITH_SAME_DEV 0
|
||||
#endif
|
||||
|
||||
// <o> support
|
||||
// <0=> NOT SUPPORT
|
||||
// <1=> SUPPORT
|
||||
#ifndef CFG_CAR_KEY_SUPPORT
|
||||
#define CFG_CAR_KEY_SUPPORT 0
|
||||
#endif
|
||||
// </h>
|
||||
|
||||
@@ -277,7 +356,7 @@
|
||||
// <0=> NOT SUPPORT
|
||||
// <1=> SUPPORT
|
||||
#ifndef CFG_MESH_SUPPORT
|
||||
#define CFG_MESH_SUPPORT 0
|
||||
#define CFG_MESH_SUPPORT 0
|
||||
#endif
|
||||
// </h>
|
||||
|
||||
@@ -286,9 +365,18 @@
|
||||
// <0=> NOT SUPPORT
|
||||
// <1=> SUPPORT
|
||||
#ifndef CFG_LCP_SUPPORT
|
||||
#define CFG_LCP_SUPPORT 0
|
||||
#define CFG_LCP_SUPPORT 0
|
||||
#endif
|
||||
// </h>
|
||||
|
||||
// <h> security configuration
|
||||
// <o> algorithm security level
|
||||
// <0=> Enable algorithm level one
|
||||
// <1=> Enable algorithm level two
|
||||
#ifndef SECURITY_CFG_VAL
|
||||
#define SECURITY_CFG_VAL 0
|
||||
#endif
|
||||
// </h>
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
#endif // __CUSTOM_CONFIG_H__
|
||||
#endif //__CUSTOM_CONFIG_H__
|
||||
|
||||
Executable → Regular
+30
-147
@@ -1,5 +1,15 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file scatter_config.h
|
||||
*
|
||||
* @brief Common scatter file definition file.
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2021 GOODIX.
|
||||
* Copyright (c) 2024 GOODIX.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
@@ -13,28 +23,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file scatter_config.h
|
||||
*
|
||||
* @brief Common scatter file definition file.
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef SCATTER_CONFIG_H
|
||||
#define SCATTER_CONFIG_H
|
||||
#ifndef __SCATTER_CONFIG_H__
|
||||
#define __SCATTER_CONFIG_H__
|
||||
|
||||
#include "custom_config.h"
|
||||
|
||||
/*****************************************************************
|
||||
* if CSTACK_HEAP_SIZE is not defined in custom_config.h,
|
||||
* if SYSTEM_STACK_SIZE is not defined in custom_config.h,
|
||||
* keep default setting to 32KB
|
||||
*/
|
||||
#ifndef CSTACK_HEAP_SIZE
|
||||
#define CSTACK_HEAP_SIZE 0x8000
|
||||
#ifndef SYSTEM_STACK_SIZE
|
||||
#define SYSTEM_STACK_SIZE 0x8000
|
||||
#endif
|
||||
|
||||
#define FLASH_START_ADDR 0x01000000
|
||||
@@ -42,7 +41,7 @@
|
||||
|
||||
/* size of ROM reserved RAM in retention cell */
|
||||
#ifndef ROM_RTN_RAM_SIZE
|
||||
#define ROM_RTN_RAM_SIZE 0x4020
|
||||
#define ROM_RTN_RAM_SIZE 0x4100
|
||||
#endif
|
||||
|
||||
#define RAM_ALIAS
|
||||
@@ -56,159 +55,42 @@
|
||||
#define RAM_START_ADDR 0x30000000
|
||||
#endif
|
||||
|
||||
#if (CHIP_TYPE == 0)
|
||||
#define RAM_SIZE 0x00040000
|
||||
#else
|
||||
#define RAM_SIZE 0x00020000
|
||||
#if (CHIP_TYPE == 6) || (CHIP_TYPE == 7) //GR5513
|
||||
#define RAM_SIZE 0x00020000
|
||||
#else //GR5515
|
||||
#define RAM_SIZE 0x00040000
|
||||
#endif
|
||||
|
||||
#define RAM_END_ADDR (RAM_START_ADDR + RAM_SIZE)
|
||||
|
||||
|
||||
#define FERP_SIZE 0x8000 // 32K
|
||||
#define FERP_SIZE 0x8000 //32K
|
||||
#define CRITICAL_CODE_MAX_SIZE 0x10000 // maximum size of critical code reserved
|
||||
|
||||
#if (APP_CODE_RUN_ADDR == APP_CODE_LOAD_ADDR && \
|
||||
APP_CODE_RUN_ADDR >= FLASH_START_ADDR && \
|
||||
APP_CODE_RUN_ADDR < FLASH_START_ADDR + FLASH_SIZE)
|
||||
#define XIP_MODE
|
||||
#define XIP_MODE
|
||||
#endif
|
||||
/****************************************************************/
|
||||
|
||||
/* ************************************************************************
|
||||
* developer must define CFG_MAX_CONNECTIONS in custom_config.h .
|
||||
* Max value for GR551X: 10 which must be same with CFG_CON
|
||||
* in ROM's configs.opt
|
||||
*/
|
||||
#ifndef CFG_MAX_CONNECTIONS
|
||||
#error "CFG_MAX_CONNECTIONS is not defined in app's custom_config.h ."
|
||||
#endif
|
||||
|
||||
#if (CFG_MAX_CONNECTIONS <= 10)
|
||||
#define USER_MAX_CONNECTIONS CFG_MAX_CONNECTIONS
|
||||
#else
|
||||
#define USER_MAX_CONNECTIONS (1)
|
||||
#endif
|
||||
|
||||
#ifndef CFG_MAX_ADVS
|
||||
#error "CFG_MAX_ADVS is not defined in app's custom_config.h ."
|
||||
#endif
|
||||
|
||||
#if (CFG_MAX_ADVS <= 5)
|
||||
#define USER_MAX_ADVS CFG_MAX_ADVS
|
||||
#else
|
||||
#define USER_MAX_ADVS (1)
|
||||
#endif
|
||||
|
||||
#ifndef CFG_MAX_PER_ADVS
|
||||
#error "CFG_MAX_PER_ADVS is not defined in app's custom_config.h ."
|
||||
#endif
|
||||
|
||||
#if (CFG_MAX_PER_ADVS <= 5)
|
||||
#define USER_MAX_PER_ADVS CFG_MAX_PER_ADVS
|
||||
#else
|
||||
#define USER_MAX_PER_ADVS (0)
|
||||
#endif
|
||||
|
||||
#if ((USER_MAX_ADVS+USER_MAX_PER_ADVS) > 5)
|
||||
#error "The number of BLE Legacy/Extended/Periodic Advertising exceeds the limit."
|
||||
#endif
|
||||
|
||||
#ifndef CFG_MAX_SCAN
|
||||
#error "CFG_MAX_SCAN is not defined in app's custom_config.h ."
|
||||
#endif
|
||||
|
||||
#if (CFG_MAX_SCAN <= 1)
|
||||
#define USER_MAX_SCAN CFG_MAX_SCAN
|
||||
#else
|
||||
#define USER_MAX_SCAN (1)
|
||||
#endif
|
||||
|
||||
#ifndef CFG_MAX_SYNCS
|
||||
#error "CFG_MAX_SYNCS is not defined in app's custom_config.h ."
|
||||
#endif
|
||||
|
||||
#if (CFG_MAX_SYNCS <= 5)
|
||||
#define USER_MAX_SYNCS CFG_MAX_SYNCS
|
||||
#else
|
||||
#define USER_MAX_SYNCS (0)
|
||||
#endif
|
||||
|
||||
#if ((USER_MAX_CONNECTIONS+USER_MAX_ADVS+2*USER_MAX_PER_ADVS+USER_MAX_SCAN+USER_MAX_SYNCS) > 12)
|
||||
#error "The number of BLE Activities exceeds the limit."
|
||||
#endif
|
||||
|
||||
#ifndef CFG_MAX_BOND_DEVS
|
||||
#error "CFG_MAX_BOND_DEVS is not defined in app's custom_config.h ."
|
||||
#endif
|
||||
|
||||
#if (CFG_MAX_BOND_DEVS <= 10)
|
||||
#define USER_MAX_BOND_DEVS CFG_MAX_BOND_DEVS
|
||||
#else
|
||||
#define USER_MAX_BOND_DEVS (1)
|
||||
#endif
|
||||
|
||||
#ifndef CFG_MAX_PRFS
|
||||
#error "CFG_MAX_PRFS is not defined in app's custom_config.h ."
|
||||
#endif
|
||||
|
||||
#if (CFG_MAX_PRFS <= 64)
|
||||
#define USER_MAX_PRFS CFG_MAX_PRFS
|
||||
#else
|
||||
#define USER_MAX_PRFS (1)
|
||||
#endif
|
||||
|
||||
/* The macro is used to compute size of the heap block in bytes. */
|
||||
#define MEM_HEAP_HEADER (12 / sizeof(uint32_t))
|
||||
#define MEM_CALC_HEAP_LEN(len) ((((len) + (sizeof(uint32_t) - 1)) / sizeof(uint32_t)) + MEM_HEAP_HEADER)
|
||||
#define MEM_CALC_HEAP_LEN_IN_BYTES(len) (MEM_CALC_HEAP_LEN(len) * sizeof(uint32_t))
|
||||
|
||||
#define ENV_HEAP_SIZE MEM_CALC_HEAP_LEN_IN_BYTES(292 * USER_MAX_CONNECTIONS + \
|
||||
426 * (USER_MAX_CONNECTIONS + USER_MAX_ADVS + \
|
||||
2 * USER_MAX_PER_ADVS+USER_MAX_SCAN+USER_MAX_SYNCS) + \
|
||||
600)
|
||||
/* The size of heap for ATT database depends on the number of attributes in
|
||||
* profiles. The value can be tuned based on supported profiles. */
|
||||
#if (CFG_MESH_SUPPORT == 1)
|
||||
#include "mesh_stack_config.h"
|
||||
#define ATT_DB_HEAP_SIZE MEM_CALC_HEAP_LEN_IN_BYTES(1000 + MESH_HEAP_SIZE_ADD)
|
||||
#else
|
||||
#define ATT_DB_HEAP_SIZE MEM_CALC_HEAP_LEN_IN_BYTES(1024)
|
||||
#endif
|
||||
|
||||
#define KE_MSG_HEAP_SIZE MEM_CALC_HEAP_LEN_IN_BYTES(1650 * (USER_MAX_SCAN+USER_MAX_SYNCS) + \
|
||||
112 *(USER_MAX_CONNECTIONS + USER_MAX_ADVS + \
|
||||
2*USER_MAX_PER_ADVS) + 408 *(USER_MAX_CONNECTIONS + \
|
||||
USER_MAX_ADVS + 2 * USER_MAX_PER_ADVS + \
|
||||
USER_MAX_SCAN + USER_MAX_SYNCS)+ 3072)
|
||||
/* The size of non-retention heap is customized. This heap will used by BLE
|
||||
* stack only when other three heaps are full. */
|
||||
#define NON_RET_HEAP_SIZE MEM_CALC_HEAP_LEN_IN_BYTES(328 * 2)
|
||||
|
||||
#define PRF_BUF_SIZE (92*USER_MAX_PRFS + 4)
|
||||
#define BOND_BUF_SIZE (8*USER_MAX_BOND_DEVS + 4)
|
||||
#define CONN_BUF_SIZE (372*USER_MAX_CONNECTIONS + 4)
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* sections on retention RAM cells */
|
||||
#ifdef CFG_FERP
|
||||
#define STACK_END_ADDR (RAM_END_ADDR-FERP_SIZE)
|
||||
#define STACK_END_ADDR (RAM_END_ADDR-FERP_SIZE)
|
||||
#else
|
||||
#define STACK_END_ADDR (RAM_END_ADDR)
|
||||
#define STACK_END_ADDR (RAM_END_ADDR)
|
||||
#endif
|
||||
|
||||
#ifndef GR5515_E
|
||||
#define USE_TINY_RAM_SPACE
|
||||
#endif
|
||||
|
||||
#define TINY_RAM_SPACE_START (RAM_START_ADDR + 0x35CC) /* DONT MODIFY ME !!! */
|
||||
#define TINY_RAM_SPACE_START (0x30000000 + 0x35CC) /* DONT MODIFY ME !!! */
|
||||
#define TINY_RAM_SPACE_SIZE (0x750) /* DONT MODIFY ME !!! */
|
||||
|
||||
#define FPB_SECTION_START 0x30004000
|
||||
#define FPB_SECTION_SIZE 0x20
|
||||
#define FPB_SECTION_SIZE 0x100
|
||||
|
||||
#define UNUSED_SECTION_SIZE 0x64
|
||||
#define RAM_RESERVE_SECTION_SIZE 0x64
|
||||
|
||||
// Code size of Application
|
||||
#ifndef APP_MAX_CODE_SIZE
|
||||
@@ -220,4 +102,5 @@
|
||||
#define APP_RAM_SIZE 0x00030000
|
||||
#endif
|
||||
|
||||
#endif // SCATTER_CONFIG_H
|
||||
#endif // __SCATTER_CONFIG_H__
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2021 GOODIX.
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
@@ -11,65 +11,13 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# This BUILD.gn is used to compile the SDK source code of Goodix GR551x SOC.
|
||||
# In this script, optionally add source code compilation. If the SDK is upgraded,
|
||||
# you can directly replace components, drivers, and toolchain folders.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [
|
||||
"components/app_drivers/inc",
|
||||
"components/boards",
|
||||
"components/drivers_ext/gr551x",
|
||||
"components/libraries/app_lfs",
|
||||
"components/libraries/app_assert",
|
||||
"components/libraries/app_error",
|
||||
"components/libraries/app_log",
|
||||
"components/libraries/app_timer",
|
||||
"components/libraries/hal_flash",
|
||||
"components/libraries/pmu_calibration",
|
||||
"components/libraries/ring_buffer",
|
||||
"components/libraries/utility",
|
||||
"components/patch/ind",
|
||||
"components/sdk/",
|
||||
"drivers/inc",
|
||||
"toolchain/gr551x/include",
|
||||
]
|
||||
}
|
||||
|
||||
kernel_module("gr551x_sdk") {
|
||||
sources = [
|
||||
"components/app_drivers/src/app_dma.c",
|
||||
"components/app_drivers/src/app_gpiote.c",
|
||||
"components/app_drivers/src/app_i2c.c",
|
||||
"components/app_drivers/src/app_io.c",
|
||||
"components/app_drivers/src/app_pwm.c",
|
||||
"components/app_drivers/src/app_pwr_mgmt.c",
|
||||
"components/app_drivers/src/app_rng.c",
|
||||
"components/app_drivers/src/app_systick.c",
|
||||
"components/app_drivers/src/app_uart.c",
|
||||
"components/libraries/app_assert/app_assert.c",
|
||||
"components/libraries/app_error/app_error.c",
|
||||
"components/libraries/app_log/app_log.c",
|
||||
"components/libraries/app_timer/app_timer.c",
|
||||
"components/libraries/pmu_calibration/pmu_calibration.c",
|
||||
"components/libraries/ring_buffer/ring_buffer.c",
|
||||
"components/libraries/utility/utility.c",
|
||||
"drivers/src/gr55xx_hal.c",
|
||||
"drivers/src/gr55xx_hal_adc.c",
|
||||
"drivers/src/gr55xx_hal_aon_gpio.c",
|
||||
"drivers/src/gr55xx_hal_aon_wdt.c",
|
||||
"drivers/src/gr55xx_hal_calendar.c",
|
||||
"drivers/src/gr55xx_hal_exflash.c",
|
||||
"drivers/src/gr55xx_hal_gpio.c",
|
||||
"drivers/src/gr55xx_hal_i2c.c",
|
||||
"drivers/src/gr55xx_hal_pwm.c",
|
||||
"drivers/src/gr55xx_hal_pwr.c",
|
||||
"drivers/src/gr55xx_hal_rng.c",
|
||||
"drivers/src/gr55xx_hal_uart.c",
|
||||
"toolchain/gr551x/source/interrupt_gr55xx.c",
|
||||
"toolchain/gr551x/source/platform_gr55xx.c",
|
||||
"toolchain/gr551x/source/system_gr55xx.c",
|
||||
module_group("gr551x_sdk") {
|
||||
modules = [
|
||||
"drivers",
|
||||
"components",
|
||||
"platform",
|
||||
"external/segger_rtt",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
# GR551x Series SoC
|
||||
|
||||
## 1. Introduction
|
||||
|
||||
- The Goodix GR551x family is a single-mode, low-power Bluetooth 5.1 System-on-Chip (SoC). It can be configured as a Broadcaster, an Observer, a Central, a Peripheral, and supports the combination of all the above roles, making it an ideal choice for Internet of Things (IoT) and smart wearable devices.
|
||||
|
||||
- Based on ARM® Cortex®-M4F CPU core, the GR551x integrates Bluetooth 5.1 Protocol Stack, a 2.4 GHz RF transceiver, on-chip programmable Flash memory, RAM, and multiple peripherals.
|
||||
|
||||
- The [GR551x SDK](https://www.goodix.com/en/software_tool/gr551x_sdk) is the software development kit for the GR551x SoC, offering a complete solution that integrates the protocol stacks, application samples and hardware drivers.
|
||||
|
||||
|
||||
|
||||
## 2. Key Features
|
||||
|
||||
- Bluetooth 5.1 transceiver integrates Controller and Host layers
|
||||
- Support these data transmission rates: 1 Mbps, 2 Mbps, LR (500 kbps, 125 kbps)
|
||||
- TX power: -20 dBm ~ +7 dBm
|
||||
- -96 dBm reception sensitivity (under the 1 Mbps mode)
|
||||
- -93 dBm reception sensitivity (under the 2 Mbps mode)
|
||||
- -99 dBm reception sensitivity (under the LR 500 kbps mode)
|
||||
- -102 dBm reception sensitivity (under the LR 125 kbps mode)
|
||||
- TX current: 5.6 mA @ 0 dBm,1 Mbps
|
||||
- RX current: 4.8 mA @ 1 Mbps
|
||||
- Built-in ARM® Cortex®-M4F 32-bit micro-processor, supporting floating-point operation
|
||||
- Maximum frequency: 64 MHz
|
||||
- Power consumption: 51 μA/MHz
|
||||
- Memory
|
||||
- Flash Configurations for GR5515 series
|
||||
- GR5515I0NDA: no embedded Flash
|
||||
- GR5515IENDU: embedded with 512 KB Flash
|
||||
- All other SoCs: embedded with 1 MB flash
|
||||
- Flash Configurations for GR5513 series
|
||||
- GR5513 series: embedded with 512 KB Flash
|
||||
- Power Management
|
||||
- On-chip DC-DC Converter
|
||||
- On-chip I/O LDO to provide I/O voltage and supply external components
|
||||
- Supply voltage: 2.2 V to 3.8 V
|
||||
- I/O voltage: 1.8 V to 3.3 V
|
||||
- OFF mode: 0.15 µA (Typical), chip in reset
|
||||
- Ultra deep sleep mode: 1.8 µA (Typical), no memory retention
|
||||
- Sleep mode: 2.7 µA (Typical), 256 KB memory retention
|
||||
|
||||
- Peripherals
|
||||
- 2 QSPI interfaces, up to 32 MHz
|
||||
- 2 SPI interfaces (1 SPI Master Interface with 2 Slave CS pins + 1 SPI Slave Interface), up to 32 MHz
|
||||
- 2 I2C interfaces (Supports 100 kHz, 400 kHz, 1 MHz, 2 MHz)
|
||||
- 2 I2S interfaces (1 I2S Master Interface + 1 I2S Slave Interface)
|
||||
- 2 UART interfaces (One with DMA channel)
|
||||
- 13-bit ADC, up to 1 Msps, 8 channels (5 external test channels and 3 internal signal channels), supporting both single-ended and differential inputs
|
||||
- ISO 7816 interface
|
||||
- Two PWM modules with edge alignment mode and center alignment mode, each with three channels
|
||||
- Built-in temperature and voltage sensors
|
||||
- 2 general-purpose, 32-bit timer modules
|
||||
- 1 dual timer module composed of two programmable 32-bit or 16-bit down counters
|
||||
- 1 AON hardware timer
|
||||
- 2 watchdog timers (one for the system and one is always-on)
|
||||
- 1 real-time counter (RTC), can be used as Calendar
|
||||
- Wake-up comparator
|
||||
- Supports up to 39 multiplexed GPIO pins
|
||||
- Security
|
||||
- Complete secure computing engine:
|
||||
- AES 128-bit/192-bit/256-bit encryption (ECB and CBC)
|
||||
- Keyed Hash Message Authentication Code(HMAC)
|
||||
- PKC
|
||||
- TRNG
|
||||
- Comprehensive security operation mechanism:
|
||||
- Secure boot
|
||||
- Encrypted firmware runs directly from Flash
|
||||
- Fuse for encrypted key storage
|
||||
- Differentiate application data key and firmware key, supporting one data per device/product
|
||||
- Packages
|
||||
- QFN56: 7 mm * 7 mm * 0.75 mm, 0.40 mm pitch
|
||||
- BGA68: 5.3 mm * 5.3 mm * 0.88 mm , 0.50 mm pitch
|
||||
- BGA55: 3.5 mm * 3.5 mm * 0.60 mm, 0.40 mm pitch
|
||||
- QFN40: 5 mm * 5 mm * 0.75 mm, 0.40 mm pitch
|
||||
- Operating temperature range: -40°C to +85°C
|
||||
|
||||
|
||||
|
||||
## 3. Production Details
|
||||
|
||||
| | | GR5515IGND | GR5515I0NDA | GR5515IENDU | GR5515GGBD | GR5515RGBD | GR5513BENDU |
|
||||
| --------------------- | ------------------ | ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | ----------------------------------------- |
|
||||
| Status | | Active | Active | Active | Active | Active | Active |
|
||||
| Protocol | Bluetooth LE [1] | 5.1 | 5.1 | 5.1 | 5.1 | 5.1 | 5.1 |
|
||||
| | Bluetooth Mesh | ● | ● | ● | ● | ● | ● |
|
||||
| Core System | CPU | Cortex®-M4F | Cortex®-M4F | Cortex®-M4F | Cortex®-M4F | Cortex®-M4F | Cortex®-M4F |
|
||||
| | Clocks | 64 MHz / 32K Hz | 64 MHz / 32 KHz | 64 MHz / 32 KHz | 64 MHz / 32 KHz | 64 MHz / 32 KHz | 64 MHz / 32 KHz |
|
||||
| | Cache | 8 KB | 8 KB | 8 KB | 8 KB | 8 KB | 8 KB |
|
||||
| | RAM | 256 KB | 256 KB | 256 KB | 256 KB | 256 KB | 128 KB |
|
||||
| | OTP | | | | | | |
|
||||
| | Flash | 1 MB | External Flash | 512 KB | 1 MB | 1 MB | 512 KB |
|
||||
| Security | Root of Trust | ● | ● | ● | ● | ● | ● |
|
||||
| | Secure Key Store | 4 | 4 | 4 | 4 | 4 | 4 |
|
||||
| | PKC | ● | ● | ● | ● | ● | ● |
|
||||
| | RSA | ● | ● | ● | ● | ● | ● |
|
||||
| | AES | ● | ● | ● | ● | ● | ● |
|
||||
| | ECC | ● | ● | ● | ● | ● | ● |
|
||||
| | TRNG | ● | ● | ● | ● | ● | ● |
|
||||
| Radio | Frequency | 2.4 GHz | 2.4 GHz | 2.4 GHz | 2.4 GHz | 2.4 GHz | 2.4 GHz |
|
||||
| | Maximum Tx Power | 7 dBm | 7 dBm | 7 dBm | 7 dBm | 7 dBm | 7 dBm |
|
||||
| | Rx Sensitivity | -96 dBm(@1Mbps) | -96 dBm(@1Mbps) | -96 dBm(@1Mbps) | -96 dBm(@1Mbps) | -96 dBm(@1Mbps) | -96 dBm(@1Mbps) |
|
||||
| Peripheral | UART | 2 | 2 | 2 | 2 | 2 | 2 |
|
||||
| | SPI | 1 * SPIM / 1 * SPIS | 1 * SPIM / 1 * SPIS | 1 * SPIM / 1 * SPIS | 1 * SPIM / 1 * SPIS | 1 * SPIM / 1 * SPIS | 1 * SPIM / 1 * SPIS |
|
||||
| | I2C | 2 | 2 | 2 | 2 | 2 | 2 |
|
||||
| | QSPI | 2 | 2 | 2 | 0 | 2 | 1 |
|
||||
| | Timers | 4 | 4 | 4 | 4 | 4 | 4 |
|
||||
| | PWM | 2 | 2 | 2 | 2 | 2 | 2 |
|
||||
| | RTC | 1 | 1 | 1 | 1 | 1 | 1 |
|
||||
| | I2S | 1 * I2SM / 1 * I2SS | 1 * I2SM / 1 * I2SS | 1 * I2SM / 1 * I2SS | 1 * I2SM / 1 * I2SS | 1 * I2SM / 1 * I2SS | 1 * I2SM / 1 * I2SS |
|
||||
| | ADC | 13-bit | 13-bit | 13-bit | 13-bit | 13-bit | 13-bit |
|
||||
| | Comparator | ● | ● | ● | ● | ● | ● |
|
||||
| | Temperature Sensor | ● | ● | ● | ● | ● | ● |
|
||||
| | GPIO | 39 | 39 | 39 | 29 | 39 | 22 |
|
||||
| Packages | Type | QFN56 | QFN56 | QFN56 | BGA55 | BGA68 | QFN40 |
|
||||
| | Dimensions | 7.0 * 7.0 mm | 7.0 * 7.0 mm | 7.0 * 7.0 mm | 3.5 *3.5 mm | 5.3 * 5.3 mm | 5.0 * 5.0 mm |
|
||||
| Certification | | PSA Level 1 SIG BQB (QDID: 119449) | PSA Level 1 SIG BQB (QDID: 119449) | PSA Level 1 SIG BQB (QDID: 119449) | PSA Level 1 SIG BQB (QDID: 119449) | PSA Level 1 SIG BQB (QDID: 119449) | PSA Level 1 SIG BQB (QDID: 119449) |
|
||||
| Operating Temperature | | -40℃ - 85℃ | -40℃ - 85℃ | -40℃ - 85℃ | -40℃ - 85℃ | -40℃ - 85℃ | -40℃ - 85℃ |
|
||||
| Supply Voltage Range | | 2.2 V - 3.8 V | 2.2 V - 3.8 V | 2.2 V - 3.8 V | 2.2 V - 3.8 V | 2.2 V - 3.8 V | 2.2 V - 3.8 V |
|
||||
| Development Kits | | GR5515 Starter Kit | GR5515 Starter Kit | GR5515 Starter Kit | GR5515 Starter Kit | GR5515 Starter Kit | GR5515 Starter Kit |
|
||||
|
||||
|
||||
|
||||
## 4. Change Log
|
||||
|
||||
- Click to view the [change log](../../wiki/Change-Notes-for-GR551x)
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
module_group("components") {
|
||||
modules = [
|
||||
"libraries",
|
||||
"profiles",
|
||||
"sdk",
|
||||
]
|
||||
}
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file gr55xx_measure_mux_signal_api.c
|
||||
*
|
||||
* @brief GR55XX MUX module.
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "grx_hal.h"
|
||||
#include "grx_sys.h"
|
||||
#include "gr55xx_measure_mux_signal_api.h"
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
#define ADC_INPUT_SRC_MUX (0x0D)
|
||||
#define MAX_SIMPLE_POINTS (4096)
|
||||
|
||||
/*
|
||||
* GLOBAL VARIABLE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* STATIC VARIABLE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static adc_handle_t gr55xx_snsadc_handle = {0};
|
||||
static double adc_offset = 0;
|
||||
static double adc_slope = 0;
|
||||
|
||||
static gr55xx_set_signal_to_mux(gr55xx_mux_signal_t my_mux_signal)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void gr55xx_mux_signal_measurement_init(void);
|
||||
{
|
||||
adc_trim_info_t adc_trim = {0};
|
||||
|
||||
gr55xx_snsadc_handle.init.channel_n = ADC_INPUT_SRC_REF;
|
||||
gr55xx_snsadc_handle.init.channel_p = ADC_INPUT_SRC_MUX;
|
||||
gr55xx_snsadc_handle.init.input_mode = ADC_INPUT_DIFFERENTIAL;
|
||||
gr55xx_snsadc_handle.init.ref_source = ADC_REF_SRC_BUF_INT;
|
||||
gr55xx_snsadc_handle.init.ref_value = ADC_REF_VALUE_0P8;
|
||||
#if !defined(GR55XXx)
|
||||
gr55xx_snsadc_handle.init.clock = ADC_CLK_1M;
|
||||
#else
|
||||
gr55xx_snsadc_handle.init.clock = ADC_CLK_1P6M;
|
||||
#endif
|
||||
hal_adc_init(&gr55xx_snsadc_handle);
|
||||
|
||||
if(SDK_SUCCESS == sys_adc_trim_get(&adc_trim))
|
||||
{
|
||||
adc_offset = (double)adc_trim.offset_int_0p8;
|
||||
adc_slope = (-1) * (double)adc_trim.slope_int_0p8;
|
||||
}
|
||||
else
|
||||
{
|
||||
adc_offset = 8362;
|
||||
adc_slope = -4754;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
double gr55xx_mux_signal_measure_average(gr55xx_mux_signal_t my_mux_signal);
|
||||
{
|
||||
uint16_t conver_buff[16] = {0};
|
||||
uint16_t average = 0;
|
||||
double test_result;
|
||||
|
||||
/* Set the fixed signal to Mux*/
|
||||
gr55xx_set_signal_to_mux(my_mux_signal);
|
||||
|
||||
/* Get the average of mux signal */
|
||||
hal_adc_poll_for_conversion(&gr55xx_snsadc_handle, conver_buff, 16);
|
||||
for(uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
average += conver_buff[8 + i];
|
||||
}
|
||||
average = average >> 3;
|
||||
test_result = (((double)average - adc_offset) / adc_slope);
|
||||
|
||||
test_result = test_result + 0.85;
|
||||
|
||||
return test_result;
|
||||
}
|
||||
|
||||
void gr55xx_mux_signal_measure_n_points(gr55xx_mux_signal_t my_mux_signal, uint32_t num, double* result_buf)
|
||||
{
|
||||
uint16_t conver_buff[MAX_SIMPLE_POINTS] = {0};
|
||||
double test_result;
|
||||
|
||||
/* Set the fixed signal to Mux*/
|
||||
gr55xx_set_signal_to_mux(my_mux_signal);
|
||||
|
||||
/* Get the average of mux signal */
|
||||
memset(&conver_buff[0], 0, 2*MAX_SIMPLE_POINTS);
|
||||
hal_adc_poll_for_conversion(&gr55xx_snsadc_handle, conver_buff, num);
|
||||
for(uint32_t i=0; i<num; i++)
|
||||
{
|
||||
test_result = (((double)conver_buff[i] - adc_offset) / adc_slope);
|
||||
test_result = test_result + 0.85;
|
||||
result_buf[i] = test_result;
|
||||
}
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file gr55xx_measure_mux_signal_api.h
|
||||
*
|
||||
* @brief Header file - GR55XX MUX module.
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#ifndef __GR55XX_MEASURE_MUX_API_H__
|
||||
#define __GR55XX_MEASURE_MUX_API_H__
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief gr55xx mux signals definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/**< MUX signal of LPD block. */
|
||||
GR55XX_MUX_SIGNAL_LPD_RESET = 0x00U,
|
||||
GR55XX_MUX_SIGNAL_LPD_POR_RST,
|
||||
GR55XX_MUX_SIGNAL_LPD_VDD_RC,
|
||||
GR55XX_MUX_SIGNAL_LPD_POC,
|
||||
GR55XX_MUX_SIGNAL_LPD_SRPG_BIAS,
|
||||
GR55XX_MUX_SIGNAL_LPD_RET_BIAS,
|
||||
GR55XX_MUX_SIGNAL_LPD_PMU_BOD,
|
||||
GR55XX_MUX_SIGNAL_LPD_VDDC_AON,
|
||||
/**< MUX signal of SensADC block. */
|
||||
GR55XX_MUX_SIGNAL_SNSADC_VREF,
|
||||
|
||||
/**< MUX signal of VDMs block. */
|
||||
GR55XX_MUX_SIGNAL_VDM_0,
|
||||
|
||||
/**< MUX signal of PD cores block. */
|
||||
GR55XX_MUX_SIGNAL_PD_SRON,
|
||||
|
||||
/**< MUX signal of EFUSE block. */
|
||||
GR55XX_MUX_SIGNAL_EFUSE_25V,
|
||||
|
||||
/**< MUX signal of Clock block. */
|
||||
GR55XX_MUX_SIGNAL_CLOCK_FS_750K,
|
||||
|
||||
/**< MUX signal of LDO block. */
|
||||
GR55XX_MUX_SIGNAL_LDO_VIO,
|
||||
|
||||
/**< MUX signal of DCDC block. */
|
||||
GR55XX_MUX_SIGNAL_DCDC_BATT_CMP,
|
||||
|
||||
GR55XX_MUX_SIGNAL_MAX,
|
||||
}gr55xx_mux_signal_t;
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize mux signal measurement modul.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void gr55xx_mux_signal_measurement_init(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Get the average value of mux signal input
|
||||
*
|
||||
* @return The volatge of mux signal. Unit (volt).
|
||||
****************************************************************************************
|
||||
*/
|
||||
double gr55xx_mux_signal_measure_average(gr55xx_mux_signal_t my_mux_signal);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Get num points value of mux signal input, num cannot over 4096
|
||||
*
|
||||
* @return The volatge of num points value of mux signal. Unit (volt).
|
||||
****************************************************************************************
|
||||
*/
|
||||
void gr55xx_mux_signal_measure_n_points(gr55xx_mux_signal_t my_mux_signal, uint32_t num, double* result_buf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __GR55XX_MEASURE_MUX_API_H__
|
||||
@@ -0,0 +1,863 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @file gr55xx_spi_flash.c
|
||||
* @author BLE Driver Team
|
||||
* @brief HAL APP module driver.
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "grx_hal.h"
|
||||
#include "gr55xx_spi_flash.h"
|
||||
|
||||
|
||||
#define SSI_HIGH_FREQ_CLOCK_PRESCALER 4u
|
||||
|
||||
#define SSI_LOW_FREQ_CLOCK_PRESCALER 8u
|
||||
|
||||
/*
|
||||
* SPI Master DEFINES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#define SPI_CLOCK_PRESCALER 8u /* The SPI CLOCK Freq = Peripheral CLK/SPI_CLOCK_PRESCALER */
|
||||
#define SPI_SOFT_CS_MODE_ENABLE 1u /* suggest to enable SOFT CS MODE */
|
||||
#define SPI_WAIT_TIMEOUT_MS 1500u /* default time(ms) for wait operation */
|
||||
|
||||
#if SPI_CLOCK_PRESCALER == 2u
|
||||
#define SPI_RX_SAMPLE_DELAY 1u
|
||||
#else
|
||||
#define SPI_RX_SAMPLE_DELAY 0u
|
||||
#endif
|
||||
|
||||
/* master spi parameters */
|
||||
#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) //pin configuration should be specified in the input of spi_flash_init
|
||||
#define MASTER_SPI_PIN_CONFIG {{APP_IO_TYPE_GPIOB, APP_IO_MUX_3, APP_IO_PIN_9, APP_IO_MODE_MUX, APP_IO_PULLUP, APP_SPI_PIN_ENABLE},\
|
||||
{APP_IO_TYPE_GPIOB, APP_IO_MUX_3, APP_IO_PIN_6, APP_IO_MODE_MUX, APP_IO_PULLUP, APP_SPI_PIN_ENABLE},\
|
||||
{APP_IO_TYPE_GPIOB, APP_IO_MUX_3, APP_IO_PIN_7, APP_IO_MODE_MUX, APP_IO_PULLUP, APP_SPI_PIN_ENABLE},\
|
||||
{APP_IO_TYPE_GPIOB, APP_IO_MUX_3, APP_IO_PIN_8, APP_IO_MODE_MUX, APP_IO_PULLUP, APP_SPI_PIN_ENABLE}}
|
||||
#else
|
||||
#define MASTER_SPI_PIN_CONFIG {{APP_IO_TYPE_GPIOA, APP_IO_MUX_1, APP_IO_PIN_15, APP_IO_MODE_MUX, APP_IO_PULLUP, APP_SPI_PIN_ENABLE},\
|
||||
{APP_IO_TYPE_GPIOA, APP_IO_MUX_1, APP_IO_PIN_12, APP_IO_MODE_MUX, APP_IO_PULLUP, APP_SPI_PIN_ENABLE},\
|
||||
{APP_IO_TYPE_GPIOA, APP_IO_MUX_1, APP_IO_PIN_13, APP_IO_MODE_MUX, APP_IO_PULLUP, APP_SPI_PIN_ENABLE},\
|
||||
{APP_IO_TYPE_GPIOA, APP_IO_MUX_1, APP_IO_PIN_14, APP_IO_MODE_MUX, APP_IO_PULLUP, APP_SPI_PIN_ENABLE}}
|
||||
#endif
|
||||
#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X)
|
||||
#define MASTER_SPI_MODE_CONFIG {DMA0, DMA0, DMA_Channel0, DMA_Channel1, SPI_WAIT_TIMEOUT_MS, 0}
|
||||
#define MASTER_SPI_CONFIG {SPI_DATASIZE_8BIT, SPI_POLARITY_LOW, SPI_PHASE_1EDGE, \
|
||||
SPI_CLOCK_PRESCALER, SPI_TIMODE_DISABLE, SPI_SLAVE_SELECT_0, SPI_RX_SAMPLE_DELAY}
|
||||
#else
|
||||
#define MASTER_SPI_MODE_CONFIG {DMA, DMA, DMA_Channel0, DMA_Channel1}
|
||||
#define MASTER_SPI_CONFIG {SPI_DATASIZE_8BIT, SPI_POLARITY_LOW, SPI_PHASE_1EDGE, \
|
||||
SPI_CLOCK_PRESCALER, SPI_TIMODE_DISABLE, SPI_SLAVE_SELECT_0}
|
||||
#endif
|
||||
|
||||
#define MASTER_SPI_PARAM_CONFIG {APP_SPI_ID_MASTER, MASTER_SPI_PIN_CONFIG, MASTER_SPI_MODE_CONFIG, MASTER_SPI_CONFIG, SPI_SOFT_CS_MODE_ENABLE}
|
||||
|
||||
/*
|
||||
* QSPI DEFINES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
/*****************************************
|
||||
* CHANGE FOLLOWING SETTINGS By YOUR CASE !
|
||||
*****************************************/
|
||||
|
||||
#define QSPI_CLOCK_PRESCALER 8u /* The QSPI CLOCK Freq = Peripheral CLK/QSPI_CLOCK_PRESCALER */
|
||||
#define QSPI_WAIT_TIMEOUT_MS 1500u /* default time(ms) for wait operation */
|
||||
#define QSPI_ID APP_QSPI_ID_0
|
||||
#define QSPI_TIMING_MODE QSPI_CLOCK_MODE_0
|
||||
|
||||
/*****************************************
|
||||
* CHANGE FOLLOWING SETTINGS CAREFULLY !
|
||||
*****************************************/
|
||||
#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X)
|
||||
#if QSPI_ID == APP_QSPI_ID_0
|
||||
#define QSPI_USED_DMA DMA0
|
||||
#define QSPI_USED_DMA_CH DMA_Channel0
|
||||
#elif QSPI_ID == APP_QSPI_ID_1
|
||||
#define QSPI_USED_DMA DMA0
|
||||
#define QSPI_USED_DMA_CH DMA_Channel1
|
||||
#else
|
||||
#define QSPI_USED_DMA DMA1
|
||||
#define QSPI_USED_DMA_CH DMA_Channel0
|
||||
#endif
|
||||
#endif
|
||||
#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X)
|
||||
#define QSPI_USED_DMA DMA
|
||||
#define QSPI_USED_DMA_CH DMA_Channel7
|
||||
#endif
|
||||
|
||||
|
||||
#if QSPI_CLOCK_PRESCALER == 2u
|
||||
#define QSPI_RX_SAMPLE_DELAY 1u
|
||||
#else
|
||||
#define QSPI_RX_SAMPLE_DELAY 0u
|
||||
#endif
|
||||
/*
|
||||
* LOCAL VARIABLE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static volatile qspi_control_t g_qspi_ctl;
|
||||
static flash_init_t g_flash_init;
|
||||
static app_spi_params_t spim_params = MASTER_SPI_PARAM_CONFIG;
|
||||
static app_qspi_params_t qspi_params;
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void spi_app_spim_callback(app_spi_evt_t *p_evt)
|
||||
{
|
||||
if (p_evt->type == APP_SPI_EVT_TX_CPLT)
|
||||
{
|
||||
g_qspi_ctl.spi_tmt_done = 1;
|
||||
}
|
||||
if (p_evt->type == APP_SPI_EVT_RX_CPLT)
|
||||
{
|
||||
g_qspi_ctl.spi_rcv_done = 1;
|
||||
}
|
||||
if (p_evt->type == APP_SPI_EVT_TX_RX_CPLT)
|
||||
{
|
||||
g_qspi_ctl.spi_tx_rx_done = 1;
|
||||
}
|
||||
if (p_evt->type == APP_SPI_EVT_ERROR)
|
||||
{
|
||||
g_qspi_ctl.spi_tmt_done = 1;
|
||||
g_qspi_ctl.spi_rcv_done = 1;
|
||||
g_qspi_ctl.spi_tx_rx_done = 1;
|
||||
printf("spi error event!!");
|
||||
}
|
||||
}
|
||||
|
||||
static void app_qspi_callback(app_qspi_evt_t *p_evt)
|
||||
{
|
||||
if (p_evt->type == APP_QSPI_EVT_TX_CPLT)
|
||||
{
|
||||
g_qspi_ctl.qspi_tmt_done = 1;
|
||||
}
|
||||
if (p_evt->type == APP_QSPI_EVT_RX_DATA)
|
||||
{
|
||||
g_qspi_ctl.qspi_rcv_done = 1;
|
||||
}
|
||||
if (p_evt->type == APP_QSPI_EVT_ERROR)
|
||||
{
|
||||
g_qspi_ctl.qspi_tmt_done = 1;
|
||||
g_qspi_ctl.qspi_rcv_done = 1;
|
||||
printf("QSPI error event!!");
|
||||
}
|
||||
}
|
||||
|
||||
static void spi_flash_write_enable(void)
|
||||
{
|
||||
uint8_t control_frame[1] = {SPI_FLASH_CMD_WREN};
|
||||
|
||||
if (FLASH_SPIM_ID == g_flash_init.spi_type)
|
||||
{
|
||||
g_qspi_ctl.spi_tmt_done = 0;
|
||||
app_spi_dma_transmit_async(g_qspi_ctl.spi_id, control_frame, sizeof(control_frame));
|
||||
while(g_qspi_ctl.spi_tmt_done == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
qspi_command_t command = {
|
||||
.instruction = SPI_FLASH_CMD_WREN,
|
||||
.address = 0,
|
||||
.instruction_size = QSPI_INSTSIZE_08_BITS,
|
||||
.address_size = QSPI_ADDRSIZE_00_BITS,
|
||||
.data_size = QSPI_DATASIZE_08_BITS,
|
||||
.dummy_cycles = 0,
|
||||
.instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI,
|
||||
.data_mode = QSPI_DATA_MODE_SPI,
|
||||
.length = 0,
|
||||
#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X)
|
||||
.clock_stretch_en = 1,
|
||||
#endif
|
||||
};
|
||||
|
||||
g_qspi_ctl.qspi_tmt_done = 0;
|
||||
app_qspi_dma_command_async(g_qspi_ctl.qspi_id, &command);
|
||||
while(g_qspi_ctl.qspi_tmt_done == 0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static uint8_t spi_flash_read_status(void)
|
||||
{
|
||||
uint8_t status = 0;
|
||||
|
||||
if (FLASH_SPIM_ID == g_flash_init.spi_type)
|
||||
{
|
||||
uint8_t cmd = SPI_FLASH_CMD_RDSR;
|
||||
|
||||
g_qspi_ctl.spi_tx_rx_done = 0;
|
||||
app_spi_dma_read_eeprom_async(g_qspi_ctl.spi_id, &cmd, &status, 1, 1);
|
||||
while(g_qspi_ctl.spi_tx_rx_done == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
qspi_command_t command = {
|
||||
.instruction = SPI_FLASH_CMD_RDSR,
|
||||
.address = 0,
|
||||
.instruction_size = QSPI_INSTSIZE_08_BITS,
|
||||
.address_size = QSPI_ADDRSIZE_00_BITS,
|
||||
.data_size = QSPI_DATASIZE_08_BITS,
|
||||
.dummy_cycles = 0,
|
||||
.instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI,
|
||||
.data_mode = QSPI_DATA_MODE_SPI,
|
||||
.length = 1,
|
||||
#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X)
|
||||
.clock_stretch_en = 1,
|
||||
#endif
|
||||
};
|
||||
g_qspi_ctl.qspi_rcv_done = 0;
|
||||
app_qspi_dma_command_receive_async(g_qspi_ctl.qspi_id, &command, &status);
|
||||
while(g_qspi_ctl.qspi_rcv_done == 0);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static uint32_t spi_flash_device_size(void)
|
||||
{
|
||||
uint32_t flash_size = 0;
|
||||
|
||||
if (FLASH_SPIM_ID == g_flash_init.spi_type)
|
||||
{
|
||||
uint8_t data[5] = {0};
|
||||
uint8_t control_frame[5] = {SPI_FLASH_CMD_SFUD, 0, 0, 0x34, DUMMY_BYTE};
|
||||
|
||||
g_qspi_ctl.spi_tx_rx_done = 0;
|
||||
app_spi_dma_read_eeprom_async(g_qspi_ctl.spi_id, control_frame, data, 5, 5);
|
||||
while(g_qspi_ctl.spi_tx_rx_done == 0);
|
||||
|
||||
if (data[0] != 0 && data[3] < 0xFF)
|
||||
{
|
||||
flash_size = ((data[3] << 24) + (data[2] << 16) + (data[1] << 8) + (data[0] << 0) + 1) / 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t data[4] = {0};
|
||||
qspi_command_t command = {
|
||||
.instruction = SPI_FLASH_CMD_SFUD, // SPI_FLASH_CMD_SFUD //SPI_FLASH_CMD_RDSR
|
||||
.address = 0x000034,
|
||||
.instruction_size = QSPI_INSTSIZE_08_BITS,
|
||||
.address_size = QSPI_ADDRSIZE_24_BITS,
|
||||
.data_size = QSPI_DATASIZE_08_BITS,
|
||||
.dummy_cycles = 8,
|
||||
.instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI,
|
||||
.data_mode = QSPI_DATA_MODE_SPI,
|
||||
.length = sizeof(data),
|
||||
#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X)
|
||||
.clock_stretch_en = 1,
|
||||
#endif
|
||||
};
|
||||
|
||||
g_qspi_ctl.qspi_rcv_done = 0;
|
||||
app_qspi_dma_command_receive_async(g_qspi_ctl.qspi_id, &command, &data[0]);
|
||||
while(g_qspi_ctl.qspi_rcv_done == 0);
|
||||
|
||||
if (data[0] != 0 && data[3] < 0xFF)
|
||||
{
|
||||
flash_size = ((data[3] << 24) + (data[2] << 16) + (data[1] << 8) + (data[0] << 0) + 1) / 8;
|
||||
}
|
||||
}
|
||||
|
||||
return flash_size;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t spim_flash_write(uint32_t address, uint8_t *buffer, uint32_t nbytes)
|
||||
{
|
||||
g_qspi_ctl.spi_tmt_done = 0;
|
||||
app_spim_dma_transmit_with_ia(g_qspi_ctl.spi_id, SPI_FLASH_CMD_PP, address, buffer, nbytes);
|
||||
while(g_qspi_ctl.spi_tmt_done == 0);
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
static uint32_t qspi_flash_write(uint32_t address, uint8_t *buffer, uint32_t nbytes)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
qspi_command_t command = {
|
||||
.instruction = SPI_FLASH_CMD_PP,
|
||||
.address = address,
|
||||
.instruction_size = QSPI_INSTSIZE_08_BITS,
|
||||
.address_size = QSPI_ADDRSIZE_24_BITS,
|
||||
.data_size = QSPI_DATASIZE_08_BITS,
|
||||
.dummy_cycles = 0,
|
||||
.instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI,
|
||||
.data_mode = QSPI_DATA_MODE_SPI,
|
||||
.length = nbytes,
|
||||
#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X)
|
||||
.clock_stretch_en = 1,
|
||||
#endif
|
||||
};
|
||||
|
||||
g_qspi_ctl.qspi_tmt_done = 0;
|
||||
ret = app_qspi_dma_command_transmit_async(g_qspi_ctl.qspi_id, &command, buffer);
|
||||
if(ret == APP_DRV_SUCCESS)
|
||||
{
|
||||
while(g_qspi_ctl.qspi_tmt_done == 0);
|
||||
return nbytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t qspi_flash_dual_write(uint32_t address, uint8_t *buffer, uint32_t nbytes)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
qspi_command_t command = {
|
||||
.instruction = SPI_FLASH_CMD_DPP,
|
||||
.address = address,
|
||||
.instruction_size = QSPI_INSTSIZE_08_BITS,
|
||||
.address_size = QSPI_ADDRSIZE_24_BITS,
|
||||
.data_size = QSPI_DATASIZE_08_BITS,
|
||||
.dummy_cycles = 0,
|
||||
.instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI,
|
||||
.data_mode = QSPI_DATA_MODE_DUALSPI,
|
||||
.length = nbytes,
|
||||
#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X)
|
||||
.clock_stretch_en = 1,
|
||||
#endif
|
||||
};
|
||||
|
||||
g_qspi_ctl.qspi_tmt_done = 0;
|
||||
ret = app_qspi_dma_command_transmit_async(g_qspi_ctl.qspi_id, &command, buffer);
|
||||
if(ret == APP_DRV_SUCCESS)
|
||||
{
|
||||
while(g_qspi_ctl.qspi_tmt_done == 0);
|
||||
return nbytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t spim_flash_read(uint32_t address, uint8_t *buffer, uint32_t nbytes)
|
||||
{
|
||||
uint8_t control_frame[4] = {0};
|
||||
|
||||
control_frame[0] = SPI_FLASH_CMD_READ;
|
||||
control_frame[1] = (address >> 16) & 0xFF;
|
||||
control_frame[2] = (address >> 8) & 0xFF;
|
||||
control_frame[3] = address & 0xFF;
|
||||
|
||||
g_qspi_ctl.spi_tx_rx_done = 0;
|
||||
app_spi_dma_read_eeprom_async(g_qspi_ctl.spi_id, control_frame, buffer, 4, nbytes);
|
||||
while(g_qspi_ctl.spi_tx_rx_done == 0);
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
static uint32_t qspi_flash_read(uint32_t address, uint8_t *buffer, uint32_t nbytes)
|
||||
{
|
||||
uint32_t ret ;
|
||||
qspi_command_t command = {
|
||||
.instruction = SPI_FLASH_CMD_READ,
|
||||
.address = address,
|
||||
.instruction_size = QSPI_INSTSIZE_08_BITS,
|
||||
.address_size = QSPI_ADDRSIZE_24_BITS,
|
||||
.data_size = QSPI_DATASIZE_08_BITS,
|
||||
.dummy_cycles = 0,
|
||||
.instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI,
|
||||
.data_mode = QSPI_DATA_MODE_SPI,
|
||||
.length = nbytes,
|
||||
#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X)
|
||||
.clock_stretch_en = 1,
|
||||
#endif
|
||||
};
|
||||
|
||||
g_qspi_ctl.qspi_rcv_done = 0;
|
||||
ret = app_qspi_dma_command_receive_async(g_qspi_ctl.qspi_id, &command, &buffer[0]);
|
||||
if(ret == APP_DRV_SUCCESS)
|
||||
{
|
||||
while(g_qspi_ctl.qspi_rcv_done == 0);
|
||||
return nbytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t qspi_flash_dual_read(uint32_t address, uint8_t *buffer, uint32_t nbytes)
|
||||
{
|
||||
uint32_t ret ;
|
||||
qspi_command_t command = {
|
||||
.instruction = SPI_FLASH_CMD_DREAD,
|
||||
.address = address,
|
||||
.instruction_size = QSPI_INSTSIZE_08_BITS,
|
||||
.address_size = QSPI_ADDRSIZE_24_BITS,
|
||||
.data_size = QSPI_DATASIZE_08_BITS,
|
||||
.dummy_cycles = 8,
|
||||
.instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI,
|
||||
.data_mode = QSPI_DATA_MODE_DUALSPI,
|
||||
.length = nbytes,
|
||||
#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X)
|
||||
.clock_stretch_en = 1,
|
||||
#endif
|
||||
};
|
||||
|
||||
g_qspi_ctl.qspi_rcv_done = 0;
|
||||
ret = app_qspi_dma_command_receive_async(g_qspi_ctl.qspi_id, &command, &buffer[0]);
|
||||
if(ret == APP_DRV_SUCCESS)
|
||||
{
|
||||
while(g_qspi_ctl.qspi_rcv_done == 0);
|
||||
return nbytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool spim_flash_sector_erase(uint32_t address)
|
||||
{
|
||||
uint8_t control_frame[4] = {0};
|
||||
uint32_t ret ;
|
||||
|
||||
control_frame[0] = SPI_FLASH_CMD_SE;
|
||||
control_frame[1] = (address >> 16) & 0xFF;
|
||||
control_frame[2] = (address >> 8) & 0xFF;
|
||||
control_frame[3] = address & 0xFF;
|
||||
|
||||
g_qspi_ctl.spi_tmt_done = 0;
|
||||
ret = app_spi_dma_transmit_async(g_qspi_ctl.spi_id, control_frame, sizeof(control_frame));
|
||||
while(g_qspi_ctl.spi_tmt_done == 0);
|
||||
|
||||
return (ret == APP_DRV_SUCCESS) ? true : false;
|
||||
}
|
||||
|
||||
bool qspi_flash_sector_erase(uint32_t address)
|
||||
{
|
||||
uint32_t ret;
|
||||
uint8_t control_frame[4] = {0};
|
||||
|
||||
control_frame[0] = SPI_FLASH_CMD_SE;
|
||||
control_frame[1] = (address >> 16) & 0xFF;
|
||||
control_frame[2] = (address >> 8) & 0xFF;
|
||||
control_frame[3] = address & 0xFF;
|
||||
|
||||
g_qspi_ctl.qspi_tmt_done = 0;
|
||||
ret = app_qspi_dma_transmit_async_ex(g_qspi_ctl.qspi_id, QSPI_DATA_MODE_SPI, QSPI_DATASIZE_08_BITS, control_frame, sizeof(control_frame));
|
||||
if(ret == APP_DRV_SUCCESS)
|
||||
{
|
||||
while(g_qspi_ctl.qspi_tmt_done == 0);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
void spi_flash_init(flash_init_t *p_flash_init)
|
||||
{
|
||||
uint16_t ret;
|
||||
|
||||
memcpy(&g_flash_init, p_flash_init, sizeof(flash_init_t));
|
||||
|
||||
if (FLASH_SPIM_ID == p_flash_init->spi_type)
|
||||
{
|
||||
if(p_flash_init->is_high_freq) {
|
||||
spim_params.init.baudrate_prescaler = SSI_HIGH_FREQ_CLOCK_PRESCALER;
|
||||
} else {
|
||||
spim_params.init.baudrate_prescaler = SSI_LOW_FREQ_CLOCK_PRESCALER;
|
||||
}
|
||||
|
||||
spim_params.pin_cfg.cs.type = p_flash_init->flash_io.spi_cs.gpio;
|
||||
spim_params.pin_cfg.cs.pin = p_flash_init->flash_io.spi_cs.pin;
|
||||
spim_params.pin_cfg.cs.mux = p_flash_init->flash_io.spi_cs.mux;
|
||||
|
||||
spim_params.pin_cfg.clk.type = p_flash_init->flash_io.spi_clk.gpio;
|
||||
spim_params.pin_cfg.clk.pin = p_flash_init->flash_io.spi_clk.pin;
|
||||
spim_params.pin_cfg.clk.mux = p_flash_init->flash_io.spi_clk.mux;
|
||||
|
||||
spim_params.pin_cfg.mosi.type = p_flash_init->flash_io.spi_io0.qspi_io0.gpio;
|
||||
spim_params.pin_cfg.mosi.pin = p_flash_init->flash_io.spi_io0.qspi_io0.pin;
|
||||
spim_params.pin_cfg.mosi.mux = p_flash_init->flash_io.spi_io0.qspi_io0.mux;
|
||||
|
||||
spim_params.pin_cfg.miso.type = p_flash_init->flash_io.spi_io1.qspi_io1.gpio;
|
||||
spim_params.pin_cfg.miso.pin = p_flash_init->flash_io.spi_io1.qspi_io1.pin;
|
||||
spim_params.pin_cfg.miso.mux = p_flash_init->flash_io.spi_io1.qspi_io1.mux;
|
||||
|
||||
g_qspi_ctl.spi_id = APP_SPI_ID_MASTER;
|
||||
spim_params.id = APP_SPI_ID_MASTER;
|
||||
|
||||
app_spi_deinit(g_qspi_ctl.spi_id);
|
||||
ret = app_spi_init(&spim_params, spi_app_spim_callback);
|
||||
if (ret != 0)
|
||||
{
|
||||
printf("SPI master initial failed! Please check the input paraments.\r\n");
|
||||
return;
|
||||
}
|
||||
ret = app_spi_dma_init(&spim_params);
|
||||
if (ret != 0)
|
||||
{
|
||||
printf("SPI master dma initial failed! Please check the input paraments.\r\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ((FLASH_QSPI_ID0 == p_flash_init->spi_type)
|
||||
||(FLASH_QSPI_ID1 == p_flash_init->spi_type)
|
||||
#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X)
|
||||
|| (FLASH_QSPI_ID2 == p_flash_init->spi_type)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if(FLASH_QSPI_ID0 == p_flash_init->spi_type){
|
||||
g_qspi_ctl.qspi_id = APP_QSPI_ID_0;
|
||||
} else if(FLASH_QSPI_ID1 == p_flash_init->spi_type){
|
||||
g_qspi_ctl.qspi_id = APP_QSPI_ID_1;
|
||||
#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X)
|
||||
} else {
|
||||
g_qspi_ctl.qspi_id = APP_QSPI_ID_2;
|
||||
#endif
|
||||
}
|
||||
|
||||
if(p_flash_init->is_high_freq) {
|
||||
qspi_params.init.clock_prescaler = SSI_HIGH_FREQ_CLOCK_PRESCALER;
|
||||
} else {
|
||||
qspi_params.init.clock_prescaler = SSI_LOW_FREQ_CLOCK_PRESCALER;
|
||||
}
|
||||
|
||||
qspi_params.init.clock_mode = QSPI_TIMING_MODE;
|
||||
if(qspi_params.init.clock_prescaler == 2)
|
||||
{
|
||||
qspi_params.init.rx_sample_delay = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
qspi_params.init.rx_sample_delay = 0;
|
||||
}
|
||||
|
||||
qspi_params.id = g_qspi_ctl.qspi_id;
|
||||
qspi_params.pin_cfg.cs.type = p_flash_init->flash_io.spi_cs.gpio;
|
||||
qspi_params.pin_cfg.cs.pin = p_flash_init->flash_io.spi_cs.pin;
|
||||
qspi_params.pin_cfg.cs.mux = p_flash_init->flash_io.spi_cs.mux;
|
||||
qspi_params.pin_cfg.cs.mode = APP_IO_MODE_MUX;
|
||||
qspi_params.pin_cfg.cs.pull = APP_IO_PULLUP;
|
||||
qspi_params.pin_cfg.cs.enable = APP_QSPI_PIN_ENABLE;
|
||||
qspi_params.pin_cfg.clk.type = p_flash_init->flash_io.spi_clk.gpio;
|
||||
qspi_params.pin_cfg.clk.pin = p_flash_init->flash_io.spi_clk.pin;
|
||||
qspi_params.pin_cfg.clk.mux = p_flash_init->flash_io.spi_clk.mux;
|
||||
qspi_params.pin_cfg.clk.mode = APP_IO_MODE_MUX;
|
||||
qspi_params.pin_cfg.clk.pull = APP_IO_PULLUP;
|
||||
qspi_params.pin_cfg.clk.enable = APP_QSPI_PIN_ENABLE;
|
||||
qspi_params.pin_cfg.io_0.type = p_flash_init->flash_io.spi_io0.qspi_io0.gpio;
|
||||
qspi_params.pin_cfg.io_0.pin = p_flash_init->flash_io.spi_io0.qspi_io0.pin;
|
||||
qspi_params.pin_cfg.io_0.mux = p_flash_init->flash_io.spi_io0.qspi_io0.mux;
|
||||
qspi_params.pin_cfg.io_0.mode = APP_IO_MODE_MUX;
|
||||
qspi_params.pin_cfg.io_0.pull = APP_IO_PULLUP;
|
||||
qspi_params.pin_cfg.io_0.enable = APP_QSPI_PIN_ENABLE;
|
||||
qspi_params.pin_cfg.io_1.type = p_flash_init->flash_io.spi_io1.qspi_io1.gpio;
|
||||
qspi_params.pin_cfg.io_1.pin = p_flash_init->flash_io.spi_io1.qspi_io1.pin;
|
||||
qspi_params.pin_cfg.io_1.mux = p_flash_init->flash_io.spi_io1.qspi_io1.mux;
|
||||
qspi_params.pin_cfg.io_1.mode = APP_IO_MODE_MUX;
|
||||
qspi_params.pin_cfg.io_1.pull = APP_IO_PULLUP;
|
||||
qspi_params.pin_cfg.io_1.enable = APP_QSPI_PIN_ENABLE;
|
||||
qspi_params.pin_cfg.io_2.type = p_flash_init->flash_io.qspi_io2.gpio;
|
||||
qspi_params.pin_cfg.io_2.pin = p_flash_init->flash_io.qspi_io2.pin;
|
||||
qspi_params.pin_cfg.io_2.mux = p_flash_init->flash_io.qspi_io2.mux;
|
||||
qspi_params.pin_cfg.io_2.mode = APP_IO_MODE_MUX;
|
||||
qspi_params.pin_cfg.io_2.pull = APP_IO_PULLUP;
|
||||
qspi_params.pin_cfg.io_2.enable = APP_QSPI_PIN_ENABLE;
|
||||
qspi_params.pin_cfg.io_3.type = p_flash_init->flash_io.qspi_io3.gpio;
|
||||
qspi_params.pin_cfg.io_3.pin = p_flash_init->flash_io.qspi_io3.pin;
|
||||
qspi_params.pin_cfg.io_3.mux = p_flash_init->flash_io.qspi_io3.mux;
|
||||
qspi_params.pin_cfg.io_3.mode = APP_IO_MODE_MUX;
|
||||
qspi_params.pin_cfg.io_3.pull = APP_IO_PULLUP;
|
||||
qspi_params.pin_cfg.io_3.enable = APP_QSPI_PIN_ENABLE;
|
||||
|
||||
qspi_params.dma_cfg.dma_instance = QSPI_USED_DMA;
|
||||
qspi_params.dma_cfg.dma_channel = QSPI_USED_DMA_CH;
|
||||
|
||||
app_qspi_dma_deinit(g_qspi_ctl.qspi_id);
|
||||
app_qspi_deinit(g_qspi_ctl.qspi_id);
|
||||
ret = app_qspi_init(&qspi_params, app_qspi_callback);
|
||||
if (ret != 0)
|
||||
{
|
||||
printf("QSPI initial failed! Please check the input paraments.");
|
||||
return ;
|
||||
}
|
||||
ret = app_qspi_dma_init(&qspi_params);
|
||||
if (ret != 0)
|
||||
{
|
||||
printf("QSPI initial dma failed! Please check the input paraments.");
|
||||
return ;
|
||||
}
|
||||
|
||||
//set qspi hold/wp pin to high
|
||||
app_io_init_t io_init = APP_IO_DEFAULT_CONFIG;
|
||||
io_init.mode = APP_IO_MODE_OUTPUT;
|
||||
io_init.pull = APP_IO_PULLUP;
|
||||
io_init.pin = qspi_params.pin_cfg.io_2.pin;
|
||||
io_init.mux = APP_IO_MUX;
|
||||
app_io_init(qspi_params.pin_cfg.io_2.type, &io_init);
|
||||
|
||||
io_init.mode = APP_IO_MODE_OUTPUT;
|
||||
io_init.pull = APP_IO_PULLUP;
|
||||
io_init.pin = qspi_params.pin_cfg.io_3.pin;
|
||||
io_init.mux = APP_IO_MUX;
|
||||
app_io_init(qspi_params.pin_cfg.io_3.type , &io_init);
|
||||
|
||||
app_io_write_pin(qspi_params.pin_cfg.io_2.type, qspi_params.pin_cfg.io_2.pin, APP_IO_PIN_SET);
|
||||
app_io_write_pin(qspi_params.pin_cfg.io_3.type, qspi_params.pin_cfg.io_3.pin, APP_IO_PIN_SET);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t spi_flash_write(uint32_t address, uint8_t *buffer, uint32_t nbytes)
|
||||
{
|
||||
uint32_t page_ofs, write_size, write_cont = nbytes;
|
||||
hal_status_t status = HAL_OK;
|
||||
|
||||
while (write_cont)
|
||||
{
|
||||
page_ofs = address & 0xFF;
|
||||
write_size = EXFLASH_SIZE_PAGE_BYTES - page_ofs;
|
||||
|
||||
if (write_cont < write_size)
|
||||
{
|
||||
write_size = write_cont;
|
||||
write_cont = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
write_cont -= write_size;
|
||||
}
|
||||
|
||||
spi_flash_write_enable();
|
||||
|
||||
if (FLASH_SPIM_ID == g_flash_init.spi_type)
|
||||
{
|
||||
spim_flash_write(address, buffer, write_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(g_flash_init.is_dual_line) {
|
||||
qspi_flash_dual_write(address, buffer, write_size);
|
||||
} else {
|
||||
qspi_flash_write(address, buffer, write_size);
|
||||
}
|
||||
}
|
||||
|
||||
while(spi_flash_read_status() & 0x1);
|
||||
|
||||
address += write_size;
|
||||
buffer += write_size;
|
||||
}
|
||||
|
||||
return ((status == HAL_OK) ? nbytes : 0);
|
||||
}
|
||||
|
||||
uint32_t spi_flash_read(uint32_t address, uint8_t *buffer, uint32_t nbytes)
|
||||
{
|
||||
uint32_t count = 0;
|
||||
|
||||
if (FLASH_SPIM_ID == g_flash_init.spi_type)
|
||||
{
|
||||
count = spim_flash_read(address, buffer, nbytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(g_flash_init.is_dual_line) {
|
||||
count = qspi_flash_dual_read(address, buffer, nbytes);
|
||||
} else {
|
||||
count = qspi_flash_read(address, buffer, nbytes);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool spi_flash_sector_erase(uint32_t address, uint32_t size)
|
||||
{
|
||||
bool status = true;
|
||||
|
||||
uint32_t erase_addr = address;
|
||||
uint32_t sector_ofs, erase_size, erase_cont = size;
|
||||
|
||||
while (erase_cont)
|
||||
{
|
||||
sector_ofs = erase_addr & 0xFFF;
|
||||
erase_size = EXFLASH_SIZE_SECTOR_BYTES - sector_ofs;
|
||||
|
||||
if (erase_cont < erase_size)
|
||||
{
|
||||
erase_size = erase_cont;
|
||||
erase_cont = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
erase_cont -= erase_size;
|
||||
}
|
||||
|
||||
spi_flash_write_enable();
|
||||
|
||||
if (FLASH_SPIM_ID == g_flash_init.spi_type)
|
||||
{
|
||||
status = spim_flash_sector_erase(erase_addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = qspi_flash_sector_erase(erase_addr);
|
||||
}
|
||||
|
||||
while(spi_flash_read_status() & 0x1);
|
||||
|
||||
erase_addr += erase_size;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
bool spi_flash_chip_erase(void)
|
||||
{
|
||||
uint32_t ret;
|
||||
uint8_t control_frame[1] = {SPI_FLASH_CMD_CE};
|
||||
|
||||
spi_flash_write_enable();
|
||||
|
||||
if (FLASH_SPIM_ID == g_flash_init.spi_type)
|
||||
{
|
||||
g_qspi_ctl.spi_tmt_done = 0;
|
||||
ret = app_spi_dma_transmit_async(g_qspi_ctl.spi_id, control_frame, sizeof(control_frame));
|
||||
while(g_qspi_ctl.spi_tmt_done == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_qspi_ctl.qspi_tmt_done = 0;
|
||||
ret = app_qspi_dma_transmit_async_ex(g_qspi_ctl.qspi_id, QSPI_DATA_MODE_SPI, QSPI_DATASIZE_08_BITS, control_frame, sizeof(control_frame));
|
||||
while(g_qspi_ctl.qspi_tmt_done == 0);
|
||||
}
|
||||
while(spi_flash_read_status() & 0x1);
|
||||
|
||||
return ((ret == APP_DRV_SUCCESS) ? true : false);
|
||||
}
|
||||
|
||||
void spi_flash_chip_reset(void)
|
||||
{
|
||||
uint8_t control_frame[1] = {SPI_FLASH_CMD_RSTEN};
|
||||
|
||||
if (FLASH_SPIM_ID == g_flash_init.spi_type)
|
||||
{
|
||||
g_qspi_ctl.spi_tmt_done = 0;
|
||||
app_spi_dma_transmit_async(g_qspi_ctl.spi_id, control_frame, sizeof(control_frame));
|
||||
while(g_qspi_ctl.spi_tmt_done == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_qspi_ctl.qspi_tmt_done = 0;
|
||||
app_qspi_dma_transmit_async_ex(g_qspi_ctl.qspi_id, QSPI_DATA_MODE_SPI, QSPI_DATASIZE_08_BITS, control_frame, sizeof(control_frame));
|
||||
while(g_qspi_ctl.qspi_tmt_done == 0);
|
||||
}
|
||||
|
||||
control_frame[0] = SPI_FLASH_CMD_RST;
|
||||
if (FLASH_SPIM_ID == g_flash_init.spi_type)
|
||||
{
|
||||
g_qspi_ctl.spi_tmt_done = 0;
|
||||
app_spi_dma_transmit_async(g_qspi_ctl.spi_id, control_frame, sizeof(control_frame));
|
||||
while(g_qspi_ctl.spi_tmt_done == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_qspi_ctl.qspi_tmt_done = 0;
|
||||
app_qspi_dma_transmit_async_ex(g_qspi_ctl.qspi_id, QSPI_DATA_MODE_SPI, QSPI_DATASIZE_08_BITS, control_frame, sizeof(control_frame));
|
||||
while(g_qspi_ctl.qspi_tmt_done == 0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t spi_flash_device_id(void)
|
||||
{
|
||||
uint8_t data[3] = {0};
|
||||
|
||||
if (FLASH_SPIM_ID == g_flash_init.spi_type)
|
||||
{
|
||||
uint8_t control_frame[1] = {SPI_FLASH_CMD_RDID};
|
||||
|
||||
g_qspi_ctl.spi_tx_rx_done = 0;
|
||||
app_spi_dma_read_eeprom_async(g_qspi_ctl.spi_id, control_frame, data, 1, 3);
|
||||
while(g_qspi_ctl.spi_tx_rx_done == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
qspi_command_t command = {
|
||||
.instruction = SPI_FLASH_CMD_RDID,
|
||||
.address = 0,
|
||||
.instruction_size = QSPI_INSTSIZE_08_BITS,
|
||||
.address_size = QSPI_ADDRSIZE_00_BITS,
|
||||
.data_size = QSPI_DATASIZE_08_BITS,
|
||||
.dummy_cycles = 0,
|
||||
.instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI,
|
||||
.data_mode = QSPI_DATA_MODE_SPI,
|
||||
.length = 3,
|
||||
#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X)
|
||||
.clock_stretch_en = 1,
|
||||
#endif
|
||||
};
|
||||
g_qspi_ctl.qspi_rcv_done = 0;
|
||||
app_qspi_dma_command_receive_async(g_qspi_ctl.qspi_id, &command, data);
|
||||
while(g_qspi_ctl.qspi_rcv_done == 0);
|
||||
}
|
||||
|
||||
return (((uint32_t)data[0] << 16) + ((uint32_t)data[1] << 8) + data[2]);
|
||||
}
|
||||
|
||||
void spi_flash_device_info(uint32_t *id, uint32_t *size)
|
||||
{
|
||||
if (NULL == id || NULL == size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
*id = spi_flash_device_id();
|
||||
*size = spi_flash_device_size();
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @file gr55xx_spi_flash.h
|
||||
* @author BLE Driver Team
|
||||
* @brief Header file containing functions prototypes of spi flash library.
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
****************************************************************************************
|
||||
*/
|
||||
#ifndef __GR55XX_SPI_FLASH_H__
|
||||
#define __GR55XX_SPI_FLASH_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "grx_hal.h"
|
||||
#include "app_io.h"
|
||||
#include "app_qspi.h"
|
||||
#include "app_qspi_dma.h"
|
||||
#include "app_spi.h"
|
||||
#include "app_spi_dma.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup Flash operation instruction macro definition
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define SPI_FLASH_CMD_WRSR 0x01
|
||||
#define SPI_FLASH_CMD_WRSR1 0x31
|
||||
#define SPI_FLASH_CMD_RDSR 0x05
|
||||
|
||||
#define SPI_FLASH_CMD_WREN 0x06
|
||||
#define SPI_FLASH_CMD_WRDI 0x04
|
||||
|
||||
#define SPI_FLASH_CMD_READ 0x03
|
||||
#define SPI_FLASH_CMD_FREAD 0x0B
|
||||
#define SPI_FLASH_CMD_DOFR 0x3B
|
||||
#define SPI_FLASH_CMD_DIOFR 0xBB
|
||||
#define SPI_FLASH_CMD_QOFR 0x6B
|
||||
#define SPI_FLASH_CMD_QIOFR 0xEB
|
||||
#define SPI_FLASH_CMD_READ_RESET 0xFF
|
||||
#define SPI_FLASH_CMD_DPP 0xA2
|
||||
#define SPI_FLASH_CMD_DREAD 0x3B
|
||||
#define SPI_FLASH_CMD_PP 0x02
|
||||
#define SPI_FLASH_CMD_SE 0x20
|
||||
#define SPI_FLASH_CMD_BE_32 0x52
|
||||
#define SPI_FLASH_CMD_BE_64 0xD8
|
||||
#define SPI_FLASH_CMD_CE 0xC7
|
||||
#define SPI_FLASH_CMD_PES 0x75
|
||||
#define SPI_FLASH_CMD_PER 0x7A
|
||||
|
||||
#define SPI_FLASH_CMD_RDI 0xAB
|
||||
#define SPI_FLASH_CMD_REMS 0x90
|
||||
#define SPI_FLASH_CMD_RDID 0x9F
|
||||
|
||||
#define SPI_FLASH_CMD_RSTEN 0x66
|
||||
#define SPI_FLASH_CMD_RST 0x99
|
||||
#define SPI_FLASH_CMD_DP 0xB9
|
||||
#define SPI_FLASH_CMD_RDP 0xAB
|
||||
|
||||
#define SPI_FLASH_CMD_SFUD 0x5A
|
||||
|
||||
#define DUMMY_BYTE 0xFF
|
||||
|
||||
#define SPI_FLASH_PAGE_SIZE 0x00100
|
||||
#define SPI_FLASH_SECTOR_SIZE 0x01000
|
||||
#define SPI_FLASH_BLOCK_SIZE 0x10000
|
||||
#define SPI_FLASH_ADDRESS_MAX 0xFFFFF
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @addtogroup Spi Flash IO configuration Structures
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
FLASH_SPIM_ID, /**< SPI master module. */
|
||||
FLASH_QSPI_ID0, /**< QSPI master module 0. */
|
||||
FLASH_QSPI_ID1, /**< QSPI master module 1. */
|
||||
#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X)
|
||||
FLASH_QSPI_ID2, /**< QSPI master module 2. */
|
||||
#endif
|
||||
FLASH_SPI_ID_MAX, /**< Only for check parameter, not used as input parameters. */
|
||||
} spi_type_t;
|
||||
|
||||
typedef struct _spi_io
|
||||
{
|
||||
app_io_type_t gpio;
|
||||
uint32_t pin;
|
||||
app_io_mux_t mux;
|
||||
} spi_io_t;
|
||||
|
||||
typedef struct _flash_io
|
||||
{
|
||||
spi_io_t spi_cs;
|
||||
spi_io_t spi_clk;
|
||||
union
|
||||
{
|
||||
spi_io_t spim_mosi;
|
||||
spi_io_t qspi_io0;
|
||||
} spi_io0;
|
||||
union
|
||||
{
|
||||
spi_io_t spim_miso;
|
||||
spi_io_t qspi_io1;
|
||||
} spi_io1;
|
||||
spi_io_t qspi_io2;
|
||||
spi_io_t qspi_io3;
|
||||
} flash_io_t;
|
||||
|
||||
typedef struct _flash_init
|
||||
{
|
||||
spi_type_t spi_type;
|
||||
flash_io_t flash_io;
|
||||
bool is_dual_line;
|
||||
bool is_high_freq;
|
||||
} flash_init_t;
|
||||
|
||||
typedef struct flash_control
|
||||
{
|
||||
uint8_t qspi_tmt_done;
|
||||
uint8_t qspi_rcv_done;
|
||||
app_qspi_id_t qspi_id;
|
||||
uint8_t spi_tmt_done;
|
||||
uint8_t spi_rcv_done;
|
||||
uint8_t spi_tx_rx_done;
|
||||
app_spi_id_t spi_id;
|
||||
} qspi_control_t;
|
||||
|
||||
/** @} */
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup HAL_SPI_FLASH_DRIVER_FUNCTIONS Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize the SPI FLASH DRIVER according to the specified parameters
|
||||
* in the spi_flash_io_t.
|
||||
*
|
||||
* @param[in] p_params: Pointer to spi_flash_io_t parameter.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void spi_flash_init(flash_init_t *p_flash_init);
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Write flash Memory.
|
||||
*
|
||||
* @param[in] address: start address in flash to write data to.
|
||||
* @param[in,out] buffer: buffer of data to write.
|
||||
* @param[in] nbytes: number of bytes to write.
|
||||
*
|
||||
* @return number of bytes written
|
||||
*******************************************************************************
|
||||
*/
|
||||
uint32_t spi_flash_write(uint32_t address, uint8_t *buffer, uint32_t nbytes);
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Read flash Memory.
|
||||
*
|
||||
* @param[in] address: start address in flash to read data.
|
||||
* @param[in,out] buffer: buffer to read data to.
|
||||
* @param[in] nbytes: number of bytes to read.
|
||||
*
|
||||
* @return number of bytes read
|
||||
*******************************************************************************
|
||||
*/
|
||||
uint32_t spi_flash_read(uint32_t address, uint8_t *buffer, uint32_t nbytes);
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Erase flash region.
|
||||
*
|
||||
* @note All sectors that have address in range of [addr, addr+len]
|
||||
* will be erased. If addr is not sector aligned, preceding data
|
||||
* on the sector that addr belongs to will also be erased.
|
||||
* If (addr + size) is not sector aligned, the whole sector
|
||||
* will also be erased.
|
||||
*
|
||||
* @param[in] address: start address in flash to write data to.
|
||||
* @param[in] size: number of bytes to write.
|
||||
*
|
||||
* @retval true: If successful.
|
||||
* @retval false: If failure.
|
||||
*******************************************************************************
|
||||
*/
|
||||
bool spi_flash_sector_erase(uint32_t address, uint32_t size);
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Erase flash chip.
|
||||
*
|
||||
* @retval true: If successful.
|
||||
* @retval false: If failure.
|
||||
*******************************************************************************
|
||||
*/
|
||||
bool spi_flash_chip_erase(void);
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Reset flash chip.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
void spi_flash_chip_reset(void);
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Get flash chip id.
|
||||
*
|
||||
* @retval Flash chip id.
|
||||
*******************************************************************************
|
||||
*/
|
||||
uint32_t spi_flash_device_id(void);
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Get Flash information.
|
||||
*
|
||||
* @param[in,out] id: Pointer to flash id.
|
||||
* @param[in,out] size: Pointer to flash size, Unit:Byte.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
void spi_flash_device_info(uint32_t *id, uint32_t *size);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __GR55XX_SPI_FLASH_H__
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file gr551x_tim_delay.c
|
||||
*
|
||||
* @brief GR551x tim delay.
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "gr551x_tim_delay.h"
|
||||
|
||||
/*
|
||||
* STATIC VARIABLE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static uint32_t fus = 0;
|
||||
static uint32_t fms = 0;
|
||||
static dual_timer_regs_t *tim_regs;
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void tim_delay_init(dual_timer_regs_t *timx)
|
||||
{
|
||||
fus = SystemCoreClock / 1000000;
|
||||
fms = SystemCoreClock / 1000;
|
||||
tim_regs = timx;
|
||||
tim_regs->RELOAD = 0xFFFFFFFF;
|
||||
/* Disable tim, period mode, 32-bit counter, one-shot mdoe */
|
||||
tim_regs->CTRL = 0x43;
|
||||
}
|
||||
|
||||
void tim_delay_us(uint32_t us)
|
||||
{
|
||||
uint32_t load = us * fus - 1;
|
||||
tim_regs->RELOAD = load;
|
||||
/* Enable tim */
|
||||
tim_regs->CTRL |= 0x80;
|
||||
while(tim_regs->VALUE != 0);
|
||||
tim_regs->CTRL &= ~0x80;
|
||||
/* Clear flag */
|
||||
tim_regs->INTCLR = 1;
|
||||
}
|
||||
|
||||
void tim_delay_ms(uint32_t ms)
|
||||
{
|
||||
uint32_t load = ms * fms - 1;
|
||||
tim_regs->RELOAD = load;
|
||||
/* Enable tim */
|
||||
tim_regs->CTRL |= 0x80;
|
||||
while(tim_regs->VALUE != 0);
|
||||
tim_regs->CTRL &= ~0x80;
|
||||
/* Clear flag */
|
||||
tim_regs->INTCLR = 1;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file gr551x_tim_delay.h
|
||||
*
|
||||
* @brief Header file - GR551x tim delay.
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#ifndef __GR551X_TIM_DELAY_H__
|
||||
#define __GR551X_TIM_DELAY_H__
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include "grx_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize the DUAL TIM according to the specified register
|
||||
* in the dual_timer_regs_t.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void tim_delay_init(dual_timer_regs_t *timx);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Delay the function execution.
|
||||
*
|
||||
* @param[in] us: Microsecond.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void tim_delay_us(uint32_t us);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Delay the function execution.
|
||||
*
|
||||
* @param[in] ms: Millisecond.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void tim_delay_ms(uint32_t ms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __GR551X_TIM_DELAY_H__
|
||||
@@ -0,0 +1,237 @@
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file st7533.c
|
||||
*
|
||||
* @brief LCD controller driver of st7735 IC.
|
||||
*
|
||||
*****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "st7735.h"
|
||||
#include "st7735_config.h"
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/*
|
||||
* GLOBAL VARIABLE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
uint16_t g_lcd_gram[LCD_YMAX][LCD_XMAX];
|
||||
uint16_t g_lcd_buffer[LCD_YMAX][LCD_XMAX];
|
||||
|
||||
/*
|
||||
* LOCAL VARIABLE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static uint16_t (*s_lcd_memory)[LCD_XMAX] = g_lcd_gram;
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static void lcd_set_window(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1)
|
||||
{
|
||||
st7735_write_cmd(0x2a);
|
||||
st7735_write_data(0x00);
|
||||
st7735_write_data(x0+0x02);
|
||||
st7735_write_data(0x00);
|
||||
st7735_write_data(x1+0x02);
|
||||
|
||||
st7735_write_cmd(0x2b);
|
||||
st7735_write_data(0x00);
|
||||
st7735_write_data(y0+0x03);
|
||||
st7735_write_data(0x00);
|
||||
st7735_write_data(y1+0x03);
|
||||
|
||||
st7735_write_cmd(0x2C);
|
||||
}
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
*******************************************************************************
|
||||
*/
|
||||
void lcd_set_memory(bool gram_set)
|
||||
{
|
||||
if(gram_set)
|
||||
{
|
||||
s_lcd_memory = g_lcd_gram;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_lcd_memory = g_lcd_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_draw_point(uint8_t x, uint8_t y, uint16_t color)
|
||||
{
|
||||
if(x > (LCD_XMAX-1) || y > (LCD_YMAX-1))
|
||||
return;
|
||||
s_lcd_memory[y][x] = color;
|
||||
}
|
||||
|
||||
|
||||
void lcd_fill_mem(uint16_t color)
|
||||
{
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
for(y=0; y<LCD_YMAX; y++)
|
||||
{
|
||||
for(x=0; x<LCD_XMAX; x++)
|
||||
{
|
||||
s_lcd_memory[y][x] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_rectangle_fill_mem(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint16_t color)
|
||||
{
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
for(y=y0; y<y1; y++)
|
||||
{
|
||||
for(x=x0; x<x1; x++)
|
||||
{
|
||||
s_lcd_memory[y][x] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_refresh(void)
|
||||
{
|
||||
lcd_set_memory(true);
|
||||
lcd_set_window(0, 0, LCD_XMAX-1, LCD_YMAX-1);
|
||||
st7735_write_buffer((uint8_t*)&s_lcd_memory[0][0], LCD_XMAX*LCD_YMAX*2);
|
||||
}
|
||||
|
||||
void lcd_rectangle_refresh(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1)
|
||||
{
|
||||
lcd_set_memory(true);
|
||||
lcd_set_window(x0, y0, x1, y1);
|
||||
st7735_write_buffer((uint8_t*)&s_lcd_memory[y0][x0], (x1-x0)*(y1-y0)*2);
|
||||
}
|
||||
|
||||
|
||||
uint16_t lcd_read_point(uint8_t x, uint8_t y)
|
||||
{
|
||||
return s_lcd_memory[y][x];
|
||||
}
|
||||
|
||||
void lcd_init(void)
|
||||
{
|
||||
st7735_init();
|
||||
//--------------------------------End ST7735S Reset Sequence --------------------------------------//
|
||||
st7735_write_cmd(0x11);
|
||||
st7735_delay(120);
|
||||
//------------------------------------ST7735S Frame Rate-----------------------------------------//
|
||||
st7735_write_cmd(0xB1);
|
||||
st7735_write_data(0x05);
|
||||
st7735_write_data(0x3C);
|
||||
st7735_write_data(0x3C);
|
||||
st7735_write_cmd(0xB2);
|
||||
st7735_write_data(0x05);
|
||||
st7735_write_data(0x3C);
|
||||
st7735_write_data(0x3C);
|
||||
st7735_write_cmd(0xB3);
|
||||
st7735_write_data(0x05);
|
||||
st7735_write_data(0x3C);
|
||||
st7735_write_data(0x3C);
|
||||
st7735_write_data(0x05);
|
||||
st7735_write_data(0x3C);
|
||||
st7735_write_data(0x3C);
|
||||
//------------------------------------End ST7735S Frame Rate---------------------------------//
|
||||
st7735_write_cmd(0xB4);
|
||||
st7735_write_data(0x03);
|
||||
//------------------------------------ST7735S Power Sequence---------------------------------//
|
||||
st7735_write_cmd(0xC0);
|
||||
st7735_write_data(0x28);
|
||||
st7735_write_data(0x08);
|
||||
st7735_write_data(0x04);
|
||||
st7735_write_cmd(0xC1);
|
||||
st7735_write_data(0XC0);
|
||||
st7735_write_cmd(0xC2);
|
||||
st7735_write_data(0x0D);
|
||||
st7735_write_data(0x00);
|
||||
st7735_write_cmd(0xC3);
|
||||
st7735_write_data(0x8D);
|
||||
st7735_write_data(0x2A);
|
||||
st7735_write_cmd(0xC4);
|
||||
st7735_write_data(0x8D);
|
||||
st7735_write_data(0xEE);
|
||||
//---------------------------------End ST7735S Power Sequence-------------------------------------//
|
||||
st7735_write_cmd(0xC5);
|
||||
st7735_write_data(0x1A);
|
||||
st7735_write_cmd(0x36);
|
||||
st7735_write_data(0xC8);
|
||||
//------------------------------------ST7735S Gamma Sequence---------------------------------//
|
||||
st7735_write_cmd(0xE0);
|
||||
st7735_write_data(0x04);
|
||||
st7735_write_data(0x22);
|
||||
st7735_write_data(0x07);
|
||||
st7735_write_data(0x0A);
|
||||
st7735_write_data(0x2E);
|
||||
st7735_write_data(0x30);
|
||||
st7735_write_data(0x25);
|
||||
st7735_write_data(0x2A);
|
||||
st7735_write_data(0x28);
|
||||
st7735_write_data(0x26);
|
||||
st7735_write_data(0x2E);
|
||||
st7735_write_data(0x3A);
|
||||
st7735_write_data(0x00);
|
||||
st7735_write_data(0x01);
|
||||
st7735_write_data(0x03);
|
||||
st7735_write_data(0x13);
|
||||
st7735_write_cmd(0xE1);
|
||||
st7735_write_data(0x04);
|
||||
st7735_write_data(0x16);
|
||||
st7735_write_data(0x06);
|
||||
st7735_write_data(0x0D);
|
||||
st7735_write_data(0x2D);
|
||||
st7735_write_data(0x26);
|
||||
st7735_write_data(0x23);
|
||||
st7735_write_data(0x27);
|
||||
st7735_write_data(0x27);
|
||||
st7735_write_data(0x25);
|
||||
st7735_write_data(0x2D);
|
||||
st7735_write_data(0x3B);
|
||||
st7735_write_data(0x00);
|
||||
st7735_write_data(0x01);
|
||||
st7735_write_data(0x04);
|
||||
st7735_write_data(0x13);
|
||||
//------------------------------------End ST7735S Gamma Sequence-----------------------------//
|
||||
st7735_write_cmd(0x3A);
|
||||
st7735_write_data(0x05);
|
||||
st7735_write_cmd(0x29);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2024 GOODIX.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT 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 __ST7735X_H__
|
||||
#define __ST7735X_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @defgroup ST7735_MAROC Defines
|
||||
* @{
|
||||
*/
|
||||
#define LCD_XMAX 128 /**< LCD Max Pixel of X coordinate. */
|
||||
#define LCD_YMAX 128 /**< LCD Max Pixel of Y coordinate. */
|
||||
|
||||
/**
|
||||
* @defgroup ST7735_EXTRERN Extern_Variable
|
||||
* @{
|
||||
*/
|
||||
extern uint16_t g_lcd_gram[LCD_YMAX][LCD_XMAX]; /**< Gram memory define. */
|
||||
extern uint16_t g_lcd_buffer[LCD_YMAX][LCD_XMAX]; /**< Buffer memory define. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup UC1701_FUNCTION Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Initialize lcd.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void lcd_init(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Resume lcd.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void lcd_resume(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Set the memory type of lcd.
|
||||
*
|
||||
* @param[in] type: Memory type.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void lcd_set_memory(bool gram_set);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Fill Data to Lcm memory.
|
||||
*
|
||||
* @param[in] data: Fill data.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void lcd_fill_mem(uint16_t color);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Refresh the memory data to lcd.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void lcd_refresh(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Draw a point to lcd memory.
|
||||
*
|
||||
* @param[in] x: X coordinate.
|
||||
* @param[in] y: Y coordinate.
|
||||
* @param[in] color: The color of the memory.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void lcd_draw_point(uint8_t x, uint8_t y, uint16_t color);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Read a point from lcd memory.
|
||||
*
|
||||
* @param[in] x: X coordinate.
|
||||
* @param[in] y: Y coordinate.
|
||||
*
|
||||
* @return The color of the read point.(Return 0xff:error)
|
||||
*****************************************************************************************
|
||||
*/
|
||||
uint16_t lcd_read_point(uint8_t x, uint8_t y);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Fill Data to Lcm rectangle memory.
|
||||
*
|
||||
* @param[in] x0: X0 coordinate.
|
||||
* @param[in] y0: Y0 coordinate.
|
||||
* @param[in] x1: X1 coordinate.
|
||||
* @param[in] y1: Y1 coordinate.
|
||||
* @param[in] color: The color of the memory.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void lcd_rectangle_fill_mem(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint16_t color);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Refresh the rectangle memory data to lcd.
|
||||
*
|
||||
* @param[in] x0: X0 coordinate.
|
||||
* @param[in] y0: Y0 coordinate.
|
||||
* @param[in] x1: X1 coordinate.
|
||||
* @param[in] y1: Y1 coordinate.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void lcd_rectangle_refresh(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file uc1701_config.c
|
||||
*
|
||||
* @brief uc1701 config Implementation.
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "st7735_config.h"
|
||||
#include "grx_hal.h"
|
||||
#include "app_spi_dma.h"
|
||||
/*
|
||||
* LOCAL VARIABLE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#ifdef DISPLAY_DRIVER_TYPE_HW_SPI
|
||||
#include "app_spi.h"
|
||||
static volatile uint8_t master_tx_done = 0;
|
||||
static void app_spi_callback(app_spi_evt_t *p_evt);
|
||||
static app_spi_params_t spi_params;
|
||||
#endif
|
||||
app_io_init_t io_init = APP_IO_DEFAULT_CONFIG;
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
*******************************************************************************
|
||||
*/
|
||||
void st7735_init(void)
|
||||
{
|
||||
io_init.mode = APP_IO_MODE_OUTPUT;
|
||||
io_init.pin = DISPLAY_BACK_LIGHT_PIN | DISPLAY_CMD_AND_DATA_PIN;
|
||||
io_init.mux = APP_IO_MUX_7;
|
||||
app_io_init(APP_IO_TYPE_GPIOA, &io_init);
|
||||
app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_BACK_LIGHT_PIN, APP_IO_PIN_SET);
|
||||
|
||||
#ifdef DISPLAY_DRIVER_TYPE_SW_IO
|
||||
io_init.mode = APP_IO_MODE_OUTPUT;
|
||||
io_init.pin = DISPLAY_SPIM_CS0_PIN | DISPLAY_SPIM_CLK_PIN | DISPLAY_SPIM_MOSI_PIN;
|
||||
io_init.mux = APP_IO_MUX_7;
|
||||
app_io_init(DISPLAY_SPIM_GPIO_TYPE, &io_init);
|
||||
#else
|
||||
spi_params.id = APP_SPI_ID_MASTER;
|
||||
|
||||
spi_params.pin_cfg.cs.type = DISPLAY_SPIM_GPIO_TYPE;
|
||||
spi_params.pin_cfg.cs.pin = DISPLAY_SPIM_CS0_PIN;
|
||||
spi_params.pin_cfg.cs.mux = APP_IO_MUX_7;
|
||||
spi_params.pin_cfg.cs.mode = APP_IO_MODE_MUX;
|
||||
spi_params.pin_cfg.cs.pull = APP_IO_PULLUP;
|
||||
spi_params.pin_cfg.cs.enable = APP_SPI_PIN_ENABLE;
|
||||
|
||||
spi_params.pin_cfg.clk.type = DISPLAY_SPIM_GPIO_TYPE;
|
||||
spi_params.pin_cfg.clk.pin = DISPLAY_SPIM_CLK_PIN;
|
||||
spi_params.pin_cfg.clk.mux = APP_IO_MUX_4;
|
||||
spi_params.pin_cfg.clk.mode = APP_IO_MODE_MUX;
|
||||
spi_params.pin_cfg.clk.pull = APP_IO_PULLUP;
|
||||
spi_params.pin_cfg.clk.enable = APP_SPI_PIN_ENABLE;
|
||||
|
||||
spi_params.pin_cfg.mosi.type = DISPLAY_SPIM_GPIO_TYPE;
|
||||
spi_params.pin_cfg.mosi.pin = DISPLAY_SPIM_MOSI_PIN;
|
||||
spi_params.pin_cfg.mosi.mux = APP_IO_MUX_4;
|
||||
spi_params.pin_cfg.mosi.mode = APP_IO_MODE_MUX;
|
||||
spi_params.pin_cfg.mosi.pull = APP_IO_PULLUP;
|
||||
spi_params.pin_cfg.mosi.enable = APP_SPI_PIN_ENABLE;
|
||||
|
||||
spi_params.pin_cfg.miso.enable = APP_SPI_PIN_DISABLE;
|
||||
|
||||
spi_params.dma_cfg.rx_dma_instance = DMA0;
|
||||
spi_params.dma_cfg.tx_dma_instance = DMA0;
|
||||
spi_params.dma_cfg.rx_dma_channel = DMA_Channel1;
|
||||
spi_params.dma_cfg.tx_dma_channel = DMA_Channel0;
|
||||
|
||||
spi_params.init.data_size = SPI_DATASIZE_8BIT;
|
||||
spi_params.init.clock_polarity = SPI_POLARITY_LOW;
|
||||
spi_params.init.clock_phase = SPI_PHASE_1EDGE;
|
||||
spi_params.init.baudrate_prescaler = SystemCoreClock / 4000000;
|
||||
spi_params.init.ti_mode = SPI_TIMODE_DISABLE;
|
||||
spi_params.init.slave_select = SPI_SLAVE_SELECT_0;
|
||||
|
||||
spi_params.is_soft_cs = 1u;
|
||||
|
||||
app_spi_init(&spi_params, app_spi_callback);
|
||||
app_spi_dma_init(&spi_params);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DISPLAY_DRIVER_TYPE_SW_IO
|
||||
/*--------------------------------DISPLAY_DRIVER_TYPE_SW_IO------------------------------------*/
|
||||
void st7735_write_cmd(uint8_t cmd)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
SEND_CMD;
|
||||
CS_LOW;
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
if (cmd &0x80)
|
||||
SDA_HIGH;
|
||||
else
|
||||
SDA_LOW;
|
||||
|
||||
SCK_LOW;
|
||||
SCK_HIGH;
|
||||
cmd <<= 1;
|
||||
}
|
||||
CS_HIGH;
|
||||
}
|
||||
|
||||
void st7735_write_data(uint8_t data)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
SEND_DATA;
|
||||
CS_LOW;
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
if(data&0x80)
|
||||
SDA_HIGH;
|
||||
else
|
||||
SDA_LOW;
|
||||
SCK_LOW;
|
||||
SCK_HIGH;
|
||||
data <<= 1;
|
||||
}
|
||||
CS_HIGH;
|
||||
}
|
||||
|
||||
void st7735_write_buffer(uint8_t *p_data, uint16_t length)
|
||||
{
|
||||
uint16_t i= 0;
|
||||
SEND_DATA;
|
||||
CS_LOW;
|
||||
for (i=0; i<length; i ++)
|
||||
{
|
||||
st7735_write_data(p_data[i]);
|
||||
}
|
||||
CS_HIGH;
|
||||
}
|
||||
|
||||
#else
|
||||
/*--------------------------------DISPLAY_DRIVER_TYPE_HW_SPI------------------------------------*/
|
||||
|
||||
static void app_spi_callback(app_spi_evt_t *p_evt)
|
||||
{
|
||||
if (p_evt->type == APP_SPI_EVT_TX_CPLT)
|
||||
{
|
||||
master_tx_done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void st7735_write_cmd(uint8_t cmd)
|
||||
{
|
||||
SEND_CMD;
|
||||
master_tx_done = 0;
|
||||
app_spi_transmit_async(APP_SPI_ID_MASTER, &cmd, 1);
|
||||
while(master_tx_done == 0);
|
||||
}
|
||||
|
||||
void st7735_write_data(uint8_t data)
|
||||
{
|
||||
SEND_DATA;
|
||||
master_tx_done = 0;
|
||||
app_spi_transmit_async(APP_SPI_ID_MASTER, &data, 1);
|
||||
while(master_tx_done == 0);
|
||||
}
|
||||
|
||||
void st7735_write_buffer(uint8_t *p_data, uint16_t length)
|
||||
{
|
||||
uint16_t last_size;
|
||||
uint16_t count_size;
|
||||
uint16_t i;
|
||||
SEND_DATA;
|
||||
if(length <= 4095)
|
||||
{
|
||||
master_tx_done = 0;
|
||||
app_spi_transmit_async(APP_SPI_ID_MASTER, p_data, length);
|
||||
while(master_tx_done == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
last_size = length % 4095;
|
||||
count_size = length / 4095;
|
||||
for(i = 0; i < count_size; i++)
|
||||
{
|
||||
master_tx_done = 0;
|
||||
app_spi_transmit_async(APP_SPI_ID_MASTER, p_data + i * 4095, 4095);
|
||||
while(master_tx_done == 0);
|
||||
}
|
||||
if(last_size)
|
||||
{
|
||||
master_tx_done = 0;
|
||||
app_spi_transmit_async(APP_SPI_ID_MASTER, p_data + i * 4095, last_size);
|
||||
while(master_tx_done == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void st7735_delay(uint16_t time)
|
||||
{
|
||||
delay_ms(time);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2024 GOODIX.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT 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 __ST7735X_CONFIG_H__
|
||||
#define __ST7735X_CONFIG_H__
|
||||
#include "board_SK.h"
|
||||
#include "app_io.h"
|
||||
|
||||
#define CS_HIGH app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_SPIM_CS0_PIN, APP_IO_PIN_SET) /**< set cs pin to high. */
|
||||
#define CS_LOW app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_SPIM_CS0_PIN, APP_IO_PIN_RESET) /**< set cs pin to low. */
|
||||
#define SEND_CMD app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_CMD_AND_DATA_PIN, APP_IO_PIN_RESET) /**< set cmd pin to high. */
|
||||
#define SEND_DATA app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_CMD_AND_DATA_PIN, APP_IO_PIN_SET) /**< set cmd pin to low. */
|
||||
|
||||
#ifdef DISPLAY_DRIVER_TYPE_SW_IO
|
||||
|
||||
#define SCK_HIGH app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_SPIM_CLK_PIN, APP_IO_PIN_SET) /**< set sck pin to high. */
|
||||
#define SCK_LOW app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_SPIM_CLK_PIN, APP_IO_PIN_RESET) /**< set sck pin to low. */
|
||||
#define SDA_HIGH app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_SPIM_MOSI_PIN, APP_IO_PIN_SET) /**< set sda pin to high. */
|
||||
#define SDA_LOW app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_SPIM_MOSI_PIN, APP_IO_PIN_RESET) /**< set sda pin to low. */
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup st7735_CONFIG_FUNCTION Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief st7735 init(config gpio spi).
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void st7735_init(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Write cmd to st7735.
|
||||
*
|
||||
* @param[in] cmd: Cmd to write.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void st7735_write_cmd(uint8_t cmd);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Write one data to st7735.
|
||||
*
|
||||
* @param[in] data: Data to write.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void st7735_write_data(uint8_t data);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Write data buffer to st7735.
|
||||
*
|
||||
* @param[in] p_data: The pointer of the data.
|
||||
* @param[in] length: The length of write data.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void st7735_write_buffer(uint8_t *p_data, uint16_t length);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief st7735 delay function.
|
||||
*
|
||||
* @param[in] time: Delay time.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void st7735_delay(uint16_t time);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
module_group("libraries") {
|
||||
modules = [
|
||||
"at_cmd",
|
||||
"fcc",
|
||||
"utility",
|
||||
"app_memory",
|
||||
"dfu_master",
|
||||
|
||||
# "virt_key",
|
||||
"app_linked_list",
|
||||
"hci_uart",
|
||||
"app_alarm",
|
||||
"ble/ble_time",
|
||||
|
||||
# "ble/ble_gatt_service",
|
||||
# "ble/ble_connect",
|
||||
# "ble/ble_scanner",
|
||||
# "ble/ble_advertising",
|
||||
"crypto_lib",
|
||||
"pmu_calibration",
|
||||
"app_timer",
|
||||
"sensorsim",
|
||||
"app_log",
|
||||
"user_efuse",
|
||||
"app_scheduler",
|
||||
"app_error",
|
||||
"app_key",
|
||||
"hal_flash",
|
||||
"app_queue",
|
||||
"dfu_port",
|
||||
"fault_trace",
|
||||
"app_assert",
|
||||
"CMSIS/cmsis_dsp",
|
||||
"ring_buffer",
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "include" ]
|
||||
lib_dirs = [ rebase_path("Lib/GCC") ]
|
||||
libs = [ "arm_cortexM4lf_math" ]
|
||||
}
|
||||
|
||||
kernel_module("cmsis_dsp") {
|
||||
}
|
||||
BIN
Binary file not shown.
+517
@@ -0,0 +1,517 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_common_tables.h
|
||||
* Description: Extern declaration for common tables
|
||||
*
|
||||
* $Date: 27. January 2017
|
||||
* $Revision: V.1.5.1
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _ARM_COMMON_TABLES_H
|
||||
#define _ARM_COMMON_TABLES_H
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES)
|
||||
/* Double Precision Float CFFT twiddles */
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREV_1024)
|
||||
extern const uint16_t armBitRevTable[1024];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_16)
|
||||
extern const uint64_t twiddleCoefF64_16[32];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_32)
|
||||
extern const uint64_t twiddleCoefF64_32[64];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_64)
|
||||
extern const uint64_t twiddleCoefF64_64[128];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_128)
|
||||
extern const uint64_t twiddleCoefF64_128[256];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_256)
|
||||
extern const uint64_t twiddleCoefF64_256[512];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_512)
|
||||
extern const uint64_t twiddleCoefF64_512[1024];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_1024)
|
||||
extern const uint64_t twiddleCoefF64_1024[2048];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_2048)
|
||||
extern const uint64_t twiddleCoefF64_2048[4096];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_4096)
|
||||
extern const uint64_t twiddleCoefF64_4096[8192];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_16)
|
||||
extern const float32_t twiddleCoef_16[32];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_32)
|
||||
extern const float32_t twiddleCoef_32[64];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_64)
|
||||
extern const float32_t twiddleCoef_64[128];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_128)
|
||||
extern const float32_t twiddleCoef_128[256];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_256)
|
||||
extern const float32_t twiddleCoef_256[512];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_512)
|
||||
extern const float32_t twiddleCoef_512[1024];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_1024)
|
||||
extern const float32_t twiddleCoef_1024[2048];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_2048)
|
||||
extern const float32_t twiddleCoef_2048[4096];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_4096)
|
||||
extern const float32_t twiddleCoef_4096[8192];
|
||||
#define twiddleCoef twiddleCoef_4096
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_16)
|
||||
extern const q31_t twiddleCoef_16_q31[24];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_32)
|
||||
extern const q31_t twiddleCoef_32_q31[48];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_64)
|
||||
extern const q31_t twiddleCoef_64_q31[96];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_128)
|
||||
extern const q31_t twiddleCoef_128_q31[192];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_256)
|
||||
extern const q31_t twiddleCoef_256_q31[384];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_512)
|
||||
extern const q31_t twiddleCoef_512_q31[768];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_1024)
|
||||
extern const q31_t twiddleCoef_1024_q31[1536];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_2048)
|
||||
extern const q31_t twiddleCoef_2048_q31[3072];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_4096)
|
||||
extern const q31_t twiddleCoef_4096_q31[6144];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_16)
|
||||
extern const q15_t twiddleCoef_16_q15[24];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_32)
|
||||
extern const q15_t twiddleCoef_32_q15[48];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_64)
|
||||
extern const q15_t twiddleCoef_64_q15[96];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_128)
|
||||
extern const q15_t twiddleCoef_128_q15[192];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_256)
|
||||
extern const q15_t twiddleCoef_256_q15[384];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_512)
|
||||
extern const q15_t twiddleCoef_512_q15[768];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_1024)
|
||||
extern const q15_t twiddleCoef_1024_q15[1536];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_2048)
|
||||
extern const q15_t twiddleCoef_2048_q15[3072];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_4096)
|
||||
extern const q15_t twiddleCoef_4096_q15[6144];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
/* Double Precision Float RFFT twiddles */
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_32)
|
||||
extern const uint64_t twiddleCoefF64_rfft_32[32];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_64)
|
||||
extern const uint64_t twiddleCoefF64_rfft_64[64];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_128)
|
||||
extern const uint64_t twiddleCoefF64_rfft_128[128];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_256)
|
||||
extern const uint64_t twiddleCoefF64_rfft_256[256];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_512)
|
||||
extern const uint64_t twiddleCoefF64_rfft_512[512];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_1024)
|
||||
extern const uint64_t twiddleCoefF64_rfft_1024[1024];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_2048)
|
||||
extern const uint64_t twiddleCoefF64_rfft_2048[2048];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_4096)
|
||||
extern const uint64_t twiddleCoefF64_rfft_4096[4096];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_32)
|
||||
extern const float32_t twiddleCoef_rfft_32[32];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_64)
|
||||
extern const float32_t twiddleCoef_rfft_64[64];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_128)
|
||||
extern const float32_t twiddleCoef_rfft_128[128];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_256)
|
||||
extern const float32_t twiddleCoef_rfft_256[256];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_512)
|
||||
extern const float32_t twiddleCoef_rfft_512[512];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_1024)
|
||||
extern const float32_t twiddleCoef_rfft_1024[1024];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_2048)
|
||||
extern const float32_t twiddleCoef_rfft_2048[2048];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_4096)
|
||||
extern const float32_t twiddleCoef_rfft_4096[4096];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
|
||||
/* Double precision floating-point bit reversal tables */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_16)
|
||||
#define ARMBITREVINDEXTABLEF64_16_TABLE_LENGTH ((uint16_t)12)
|
||||
extern const uint16_t armBitRevIndexTableF64_16[ARMBITREVINDEXTABLEF64_16_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_32)
|
||||
#define ARMBITREVINDEXTABLEF64_32_TABLE_LENGTH ((uint16_t)24)
|
||||
extern const uint16_t armBitRevIndexTableF64_32[ARMBITREVINDEXTABLEF64_32_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_64)
|
||||
#define ARMBITREVINDEXTABLEF64_64_TABLE_LENGTH ((uint16_t)56)
|
||||
extern const uint16_t armBitRevIndexTableF64_64[ARMBITREVINDEXTABLEF64_64_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_128)
|
||||
#define ARMBITREVINDEXTABLEF64_128_TABLE_LENGTH ((uint16_t)112)
|
||||
extern const uint16_t armBitRevIndexTableF64_128[ARMBITREVINDEXTABLEF64_128_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_256)
|
||||
#define ARMBITREVINDEXTABLEF64_256_TABLE_LENGTH ((uint16_t)240)
|
||||
extern const uint16_t armBitRevIndexTableF64_256[ARMBITREVINDEXTABLEF64_256_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_512)
|
||||
#define ARMBITREVINDEXTABLEF64_512_TABLE_LENGTH ((uint16_t)480)
|
||||
extern const uint16_t armBitRevIndexTableF64_512[ARMBITREVINDEXTABLEF64_512_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_1024)
|
||||
#define ARMBITREVINDEXTABLEF64_1024_TABLE_LENGTH ((uint16_t)992)
|
||||
extern const uint16_t armBitRevIndexTableF64_1024[ARMBITREVINDEXTABLEF64_1024_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_2048)
|
||||
#define ARMBITREVINDEXTABLEF64_2048_TABLE_LENGTH ((uint16_t)1984)
|
||||
extern const uint16_t armBitRevIndexTableF64_2048[ARMBITREVINDEXTABLEF64_2048_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_4096)
|
||||
#define ARMBITREVINDEXTABLEF64_4096_TABLE_LENGTH ((uint16_t)4032)
|
||||
extern const uint16_t armBitRevIndexTableF64_4096[ARMBITREVINDEXTABLEF64_4096_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
/* floating-point bit reversal tables */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_16)
|
||||
#define ARMBITREVINDEXTABLE_16_TABLE_LENGTH ((uint16_t)20)
|
||||
extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE_16_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_32)
|
||||
#define ARMBITREVINDEXTABLE_32_TABLE_LENGTH ((uint16_t)48)
|
||||
extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE_32_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_64)
|
||||
#define ARMBITREVINDEXTABLE_64_TABLE_LENGTH ((uint16_t)56)
|
||||
extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE_64_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_128)
|
||||
#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208)
|
||||
extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_256)
|
||||
#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440)
|
||||
extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_512)
|
||||
#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448)
|
||||
extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_1024)
|
||||
#define ARMBITREVINDEXTABLE_1024_TABLE_LENGTH ((uint16_t)1800)
|
||||
extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE_1024_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_2048)
|
||||
#define ARMBITREVINDEXTABLE_2048_TABLE_LENGTH ((uint16_t)3808)
|
||||
extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE_2048_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_4096)
|
||||
#define ARMBITREVINDEXTABLE_4096_TABLE_LENGTH ((uint16_t)4032)
|
||||
extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE_4096_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
|
||||
/* fixed-point bit reversal tables */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_16)
|
||||
#define ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH ((uint16_t)12)
|
||||
extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_32)
|
||||
#define ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH ((uint16_t)24)
|
||||
extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_64)
|
||||
#define ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH ((uint16_t)56)
|
||||
extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_128)
|
||||
#define ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH ((uint16_t)112)
|
||||
extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_256)
|
||||
#define ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH ((uint16_t)240)
|
||||
extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_512)
|
||||
#define ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH ((uint16_t)480)
|
||||
extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_1024)
|
||||
#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992)
|
||||
extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_2048)
|
||||
#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984)
|
||||
extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_4096)
|
||||
#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032)
|
||||
extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_F32)
|
||||
extern const float32_t realCoefA[8192];
|
||||
extern const float32_t realCoefB[8192];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_Q31)
|
||||
extern const q31_t realCoefAQ31[8192];
|
||||
extern const q31_t realCoefBQ31[8192];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_Q15)
|
||||
extern const q15_t realCoefAQ15[8192];
|
||||
extern const q15_t realCoefBQ15[8192];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_128)
|
||||
extern const float32_t Weights_128[256];
|
||||
extern const float32_t cos_factors_128[128];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_512)
|
||||
extern const float32_t Weights_512[1024];
|
||||
extern const float32_t cos_factors_512[512];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_2048)
|
||||
extern const float32_t Weights_2048[4096];
|
||||
extern const float32_t cos_factors_2048[2048];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_8192)
|
||||
extern const float32_t Weights_8192[16384];
|
||||
extern const float32_t cos_factors_8192[8192];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_128)
|
||||
extern const q15_t WeightsQ15_128[256];
|
||||
extern const q15_t cos_factorsQ15_128[128];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_512)
|
||||
extern const q15_t WeightsQ15_512[1024];
|
||||
extern const q15_t cos_factorsQ15_512[512];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_2048)
|
||||
extern const q15_t WeightsQ15_2048[4096];
|
||||
extern const q15_t cos_factorsQ15_2048[2048];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_8192)
|
||||
extern const q15_t WeightsQ15_8192[16384];
|
||||
extern const q15_t cos_factorsQ15_8192[8192];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_128)
|
||||
extern const q31_t WeightsQ31_128[256];
|
||||
extern const q31_t cos_factorsQ31_128[128];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_512)
|
||||
extern const q31_t WeightsQ31_512[1024];
|
||||
extern const q31_t cos_factorsQ31_512[512];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_2048)
|
||||
extern const q31_t WeightsQ31_2048[4096];
|
||||
extern const q31_t cos_factorsQ31_2048[2048];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_8192)
|
||||
extern const q31_t WeightsQ31_8192[16384];
|
||||
extern const q31_t cos_factorsQ31_8192[8192];
|
||||
#endif
|
||||
|
||||
#endif /* if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FAST_ALLOW_TABLES)
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_RECIP_Q15)
|
||||
extern const q15_t armRecipTableQ15[64];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_RECIP_Q31)
|
||||
extern const q31_t armRecipTableQ31[64];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */
|
||||
|
||||
/* Tables for Fast Math Sine and Cosine */
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_F32)
|
||||
extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_Q31)
|
||||
extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_Q15)
|
||||
extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */
|
||||
|
||||
#if defined(ARM_MATH_MVEI)
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_FAST_SQRT_Q31_MVE)
|
||||
extern const q31_t sqrtTable_Q31[256];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */
|
||||
#endif
|
||||
|
||||
#if defined(ARM_MATH_MVEI)
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_FAST_SQRT_Q15_MVE)
|
||||
extern const q15_t sqrtTable_Q15[256];
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */
|
||||
#endif
|
||||
|
||||
#endif /* if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FAST_TABLES) */
|
||||
|
||||
#if (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE)
|
||||
extern const float32_t exp_tab[8];
|
||||
extern const float32_t __logf_lut_f32[8];
|
||||
#endif /* (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE) */
|
||||
|
||||
#if (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM))
|
||||
extern const unsigned char hwLUT[256];
|
||||
#endif /* (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM)) */
|
||||
|
||||
#endif /* ARM_COMMON_TABLES_H */
|
||||
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_const_structs.h
|
||||
* Description: Constant structs that are initialized for user convenience.
|
||||
* For example, some can be given as arguments to the arm_cfft_f32() function.
|
||||
*
|
||||
* $Date: 27. January 2017
|
||||
* $Revision: V.1.5.1
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _ARM_CONST_STRUCTS_H
|
||||
#define _ARM_CONST_STRUCTS_H
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_common_tables.h"
|
||||
|
||||
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len16;
|
||||
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len32;
|
||||
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len64;
|
||||
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len128;
|
||||
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len256;
|
||||
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len512;
|
||||
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len1024;
|
||||
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len2048;
|
||||
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len4096;
|
||||
|
||||
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16;
|
||||
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32;
|
||||
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64;
|
||||
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128;
|
||||
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256;
|
||||
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512;
|
||||
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024;
|
||||
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048;
|
||||
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096;
|
||||
|
||||
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16;
|
||||
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32;
|
||||
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64;
|
||||
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128;
|
||||
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256;
|
||||
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512;
|
||||
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024;
|
||||
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048;
|
||||
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096;
|
||||
|
||||
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16;
|
||||
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32;
|
||||
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64;
|
||||
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128;
|
||||
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256;
|
||||
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512;
|
||||
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024;
|
||||
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048;
|
||||
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096;
|
||||
|
||||
#endif
|
||||
+8970
File diff suppressed because it is too large
Load Diff
+235
@@ -0,0 +1,235 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mve_tables.h
|
||||
* Description: common tables like fft twiddle factors, Bitreverse, reciprocal etc
|
||||
* used for MVE implementation only
|
||||
*
|
||||
* $Date: 08. January 2020
|
||||
* $Revision: V1.7.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _ARM_MVE_TABLES_H
|
||||
#define _ARM_MVE_TABLES_H
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES)
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_16) || defined(ARM_TABLE_TWIDDLECOEF_F32_32)
|
||||
|
||||
extern uint32_t rearranged_twiddle_tab_stride1_arr_16_f32[2];
|
||||
extern uint32_t rearranged_twiddle_tab_stride2_arr_16_f32[2];
|
||||
extern uint32_t rearranged_twiddle_tab_stride3_arr_16_f32[2];
|
||||
extern float32_t rearranged_twiddle_stride1_16_f32[8];
|
||||
extern float32_t rearranged_twiddle_stride2_16_f32[8];
|
||||
extern float32_t rearranged_twiddle_stride3_16_f32[8];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_64) || defined(ARM_TABLE_TWIDDLECOEF_F32_128)
|
||||
|
||||
extern uint32_t rearranged_twiddle_tab_stride1_arr_64_f32[3];
|
||||
extern uint32_t rearranged_twiddle_tab_stride2_arr_64_f32[3];
|
||||
extern uint32_t rearranged_twiddle_tab_stride3_arr_64_f32[3];
|
||||
extern float32_t rearranged_twiddle_stride1_64_f32[40];
|
||||
extern float32_t rearranged_twiddle_stride2_64_f32[40];
|
||||
extern float32_t rearranged_twiddle_stride3_64_f32[40];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_256) || defined(ARM_TABLE_TWIDDLECOEF_F32_512)
|
||||
|
||||
extern uint32_t rearranged_twiddle_tab_stride1_arr_256_f32[4];
|
||||
extern uint32_t rearranged_twiddle_tab_stride2_arr_256_f32[4];
|
||||
extern uint32_t rearranged_twiddle_tab_stride3_arr_256_f32[4];
|
||||
extern float32_t rearranged_twiddle_stride1_256_f32[168];
|
||||
extern float32_t rearranged_twiddle_stride2_256_f32[168];
|
||||
extern float32_t rearranged_twiddle_stride3_256_f32[168];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_1024) || defined(ARM_TABLE_TWIDDLECOEF_F32_2048)
|
||||
|
||||
extern uint32_t rearranged_twiddle_tab_stride1_arr_1024_f32[5];
|
||||
extern uint32_t rearranged_twiddle_tab_stride2_arr_1024_f32[5];
|
||||
extern uint32_t rearranged_twiddle_tab_stride3_arr_1024_f32[5];
|
||||
extern float32_t rearranged_twiddle_stride1_1024_f32[680];
|
||||
extern float32_t rearranged_twiddle_stride2_1024_f32[680];
|
||||
extern float32_t rearranged_twiddle_stride3_1024_f32[680];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_4096) || defined(ARM_TABLE_TWIDDLECOEF_F32_8192)
|
||||
|
||||
extern uint32_t rearranged_twiddle_tab_stride1_arr_4096_f32[6];
|
||||
extern uint32_t rearranged_twiddle_tab_stride2_arr_4096_f32[6];
|
||||
extern uint32_t rearranged_twiddle_tab_stride3_arr_4096_f32[6];
|
||||
extern float32_t rearranged_twiddle_stride1_4096_f32[2728];
|
||||
extern float32_t rearranged_twiddle_stride2_4096_f32[2728];
|
||||
extern float32_t rearranged_twiddle_stride3_4096_f32[2728];
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */
|
||||
|
||||
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
|
||||
|
||||
|
||||
|
||||
#if defined(ARM_MATH_MVEI)
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES)
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_16) || defined(ARM_TABLE_TWIDDLECOEF_Q31_32)
|
||||
|
||||
extern uint32_t rearranged_twiddle_tab_stride1_arr_16_q31[2];
|
||||
extern uint32_t rearranged_twiddle_tab_stride2_arr_16_q31[2];
|
||||
extern uint32_t rearranged_twiddle_tab_stride3_arr_16_q31[2];
|
||||
extern q31_t rearranged_twiddle_stride1_16_q31[8];
|
||||
extern q31_t rearranged_twiddle_stride2_16_q31[8];
|
||||
extern q31_t rearranged_twiddle_stride3_16_q31[8];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_64) || defined(ARM_TABLE_TWIDDLECOEF_Q31_128)
|
||||
|
||||
extern uint32_t rearranged_twiddle_tab_stride1_arr_64_q31[3];
|
||||
extern uint32_t rearranged_twiddle_tab_stride2_arr_64_q31[3];
|
||||
extern uint32_t rearranged_twiddle_tab_stride3_arr_64_q31[3];
|
||||
extern q31_t rearranged_twiddle_stride1_64_q31[40];
|
||||
extern q31_t rearranged_twiddle_stride2_64_q31[40];
|
||||
extern q31_t rearranged_twiddle_stride3_64_q31[40];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_256) || defined(ARM_TABLE_TWIDDLECOEF_Q31_512)
|
||||
|
||||
extern uint32_t rearranged_twiddle_tab_stride1_arr_256_q31[4];
|
||||
extern uint32_t rearranged_twiddle_tab_stride2_arr_256_q31[4];
|
||||
extern uint32_t rearranged_twiddle_tab_stride3_arr_256_q31[4];
|
||||
extern q31_t rearranged_twiddle_stride1_256_q31[168];
|
||||
extern q31_t rearranged_twiddle_stride2_256_q31[168];
|
||||
extern q31_t rearranged_twiddle_stride3_256_q31[168];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_1024) || defined(ARM_TABLE_TWIDDLECOEF_Q31_2048)
|
||||
|
||||
extern uint32_t rearranged_twiddle_tab_stride1_arr_1024_q31[5];
|
||||
extern uint32_t rearranged_twiddle_tab_stride2_arr_1024_q31[5];
|
||||
extern uint32_t rearranged_twiddle_tab_stride3_arr_1024_q31[5];
|
||||
extern q31_t rearranged_twiddle_stride1_1024_q31[680];
|
||||
extern q31_t rearranged_twiddle_stride2_1024_q31[680];
|
||||
extern q31_t rearranged_twiddle_stride3_1024_q31[680];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_4096) || defined(ARM_TABLE_TWIDDLECOEF_Q31_8192)
|
||||
|
||||
extern uint32_t rearranged_twiddle_tab_stride1_arr_4096_q31[6];
|
||||
extern uint32_t rearranged_twiddle_tab_stride2_arr_4096_q31[6];
|
||||
extern uint32_t rearranged_twiddle_tab_stride3_arr_4096_q31[6];
|
||||
extern q31_t rearranged_twiddle_stride1_4096_q31[2728];
|
||||
extern q31_t rearranged_twiddle_stride2_4096_q31[2728];
|
||||
extern q31_t rearranged_twiddle_stride3_4096_q31[2728];
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */
|
||||
|
||||
#endif /* defined(ARM_MATH_MVEI) */
|
||||
|
||||
|
||||
|
||||
#if defined(ARM_MATH_MVEI)
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES)
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_16) || defined(ARM_TABLE_TWIDDLECOEF_Q15_32)
|
||||
|
||||
extern uint32_t rearranged_twiddle_tab_stride1_arr_16_q15[2];
|
||||
extern uint32_t rearranged_twiddle_tab_stride2_arr_16_q15[2];
|
||||
extern uint32_t rearranged_twiddle_tab_stride3_arr_16_q15[2];
|
||||
extern q15_t rearranged_twiddle_stride1_16_q15[8];
|
||||
extern q15_t rearranged_twiddle_stride2_16_q15[8];
|
||||
extern q15_t rearranged_twiddle_stride3_16_q15[8];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_64) || defined(ARM_TABLE_TWIDDLECOEF_Q15_128)
|
||||
|
||||
extern uint32_t rearranged_twiddle_tab_stride1_arr_64_q15[3];
|
||||
extern uint32_t rearranged_twiddle_tab_stride2_arr_64_q15[3];
|
||||
extern uint32_t rearranged_twiddle_tab_stride3_arr_64_q15[3];
|
||||
extern q15_t rearranged_twiddle_stride1_64_q15[40];
|
||||
extern q15_t rearranged_twiddle_stride2_64_q15[40];
|
||||
extern q15_t rearranged_twiddle_stride3_64_q15[40];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_256) || defined(ARM_TABLE_TWIDDLECOEF_Q15_512)
|
||||
|
||||
extern uint32_t rearranged_twiddle_tab_stride1_arr_256_q15[4];
|
||||
extern uint32_t rearranged_twiddle_tab_stride2_arr_256_q15[4];
|
||||
extern uint32_t rearranged_twiddle_tab_stride3_arr_256_q15[4];
|
||||
extern q15_t rearranged_twiddle_stride1_256_q15[168];
|
||||
extern q15_t rearranged_twiddle_stride2_256_q15[168];
|
||||
extern q15_t rearranged_twiddle_stride3_256_q15[168];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_1024) || defined(ARM_TABLE_TWIDDLECOEF_Q15_2048)
|
||||
|
||||
extern uint32_t rearranged_twiddle_tab_stride1_arr_1024_q15[5];
|
||||
extern uint32_t rearranged_twiddle_tab_stride2_arr_1024_q15[5];
|
||||
extern uint32_t rearranged_twiddle_tab_stride3_arr_1024_q15[5];
|
||||
extern q15_t rearranged_twiddle_stride1_1024_q15[680];
|
||||
extern q15_t rearranged_twiddle_stride2_1024_q15[680];
|
||||
extern q15_t rearranged_twiddle_stride3_1024_q15[680];
|
||||
#endif
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_4096) || defined(ARM_TABLE_TWIDDLECOEF_Q15_8192)
|
||||
|
||||
extern uint32_t rearranged_twiddle_tab_stride1_arr_4096_q15[6];
|
||||
extern uint32_t rearranged_twiddle_tab_stride2_arr_4096_q15[6];
|
||||
extern uint32_t rearranged_twiddle_tab_stride3_arr_4096_q15[6];
|
||||
extern q15_t rearranged_twiddle_stride1_4096_q15[2728];
|
||||
extern q15_t rearranged_twiddle_stride2_4096_q15[2728];
|
||||
extern q15_t rearranged_twiddle_stride3_4096_q15[2728];
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */
|
||||
|
||||
#endif /* defined(ARM_MATH_MVEI) */
|
||||
|
||||
|
||||
|
||||
#if defined(ARM_MATH_MVEI)
|
||||
|
||||
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES)
|
||||
|
||||
|
||||
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */
|
||||
|
||||
#endif /* defined(ARM_MATH_MVEI) */
|
||||
|
||||
|
||||
|
||||
#endif /*_ARM_MVE_TABLES_H*/
|
||||
|
||||
+372
@@ -0,0 +1,372 @@
|
||||
/******************************************************************************
|
||||
* @file arm_vec_math.h
|
||||
* @brief Public header file for CMSIS DSP Library
|
||||
* @version V1.7.0
|
||||
* @date 15. October 2019
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2010-2019 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _ARM_VEC_MATH_H
|
||||
#define _ARM_VEC_MATH_H
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_common_tables.h"
|
||||
#include "arm_helium_utils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE)
|
||||
|
||||
#define INV_NEWTON_INIT_F32 0x7EF127EA
|
||||
|
||||
static const float32_t __logf_rng_f32=0.693147180f;
|
||||
|
||||
|
||||
/* fast inverse approximation (3x newton) */
|
||||
__STATIC_INLINE f32x4_t vrecip_medprec_f32(
|
||||
f32x4_t x)
|
||||
{
|
||||
q31x4_t m;
|
||||
f32x4_t b;
|
||||
any32x4_t xinv;
|
||||
f32x4_t ax = vabsq(x);
|
||||
|
||||
xinv.f = ax;
|
||||
m = 0x3F800000 - (xinv.i & 0x7F800000);
|
||||
xinv.i = xinv.i + m;
|
||||
xinv.f = 1.41176471f - 0.47058824f * xinv.f;
|
||||
xinv.i = xinv.i + m;
|
||||
|
||||
b = 2.0f - xinv.f * ax;
|
||||
xinv.f = xinv.f * b;
|
||||
|
||||
b = 2.0f - xinv.f * ax;
|
||||
xinv.f = xinv.f * b;
|
||||
|
||||
b = 2.0f - xinv.f * ax;
|
||||
xinv.f = xinv.f * b;
|
||||
|
||||
xinv.f = vdupq_m(xinv.f, INFINITY, vcmpeqq(x, 0.0f));
|
||||
/*
|
||||
* restore sign
|
||||
*/
|
||||
xinv.f = vnegq_m(xinv.f, xinv.f, vcmpltq(x, 0.0f));
|
||||
|
||||
return xinv.f;
|
||||
}
|
||||
|
||||
/* fast inverse approximation (4x newton) */
|
||||
__STATIC_INLINE f32x4_t vrecip_hiprec_f32(
|
||||
f32x4_t x)
|
||||
{
|
||||
q31x4_t m;
|
||||
f32x4_t b;
|
||||
any32x4_t xinv;
|
||||
f32x4_t ax = vabsq(x);
|
||||
|
||||
xinv.f = ax;
|
||||
|
||||
m = 0x3F800000 - (xinv.i & 0x7F800000);
|
||||
xinv.i = xinv.i + m;
|
||||
xinv.f = 1.41176471f - 0.47058824f * xinv.f;
|
||||
xinv.i = xinv.i + m;
|
||||
|
||||
b = 2.0f - xinv.f * ax;
|
||||
xinv.f = xinv.f * b;
|
||||
|
||||
b = 2.0f - xinv.f * ax;
|
||||
xinv.f = xinv.f * b;
|
||||
|
||||
b = 2.0f - xinv.f * ax;
|
||||
xinv.f = xinv.f * b;
|
||||
|
||||
b = 2.0f - xinv.f * ax;
|
||||
xinv.f = xinv.f * b;
|
||||
|
||||
xinv.f = vdupq_m(xinv.f, INFINITY, vcmpeqq(x, 0.0f));
|
||||
/*
|
||||
* restore sign
|
||||
*/
|
||||
xinv.f = vnegq_m(xinv.f, xinv.f, vcmpltq(x, 0.0f));
|
||||
|
||||
return xinv.f;
|
||||
}
|
||||
|
||||
__STATIC_INLINE f32x4_t vdiv_f32(
|
||||
f32x4_t num, f32x4_t den)
|
||||
{
|
||||
return vmulq(num, vrecip_hiprec_f32(den));
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Single-precision taylor dev.
|
||||
@param[in] x f32 quad vector input
|
||||
@param[in] coeffs f32 quad vector coeffs
|
||||
@return destination f32 quad vector
|
||||
*/
|
||||
|
||||
__STATIC_INLINE f32x4_t vtaylor_polyq_f32(
|
||||
f32x4_t x,
|
||||
const float32_t * coeffs)
|
||||
{
|
||||
f32x4_t A = vfmasq(vdupq_n_f32(coeffs[4]), x, coeffs[0]);
|
||||
f32x4_t B = vfmasq(vdupq_n_f32(coeffs[6]), x, coeffs[2]);
|
||||
f32x4_t C = vfmasq(vdupq_n_f32(coeffs[5]), x, coeffs[1]);
|
||||
f32x4_t D = vfmasq(vdupq_n_f32(coeffs[7]), x, coeffs[3]);
|
||||
f32x4_t x2 = vmulq(x, x);
|
||||
f32x4_t x4 = vmulq(x2, x2);
|
||||
f32x4_t res = vfmaq(vfmaq_f32(A, B, x2), vfmaq_f32(C, D, x2), x4);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
__STATIC_INLINE f32x4_t vmant_exp_f32(
|
||||
f32x4_t x,
|
||||
int32x4_t * e)
|
||||
{
|
||||
any32x4_t r;
|
||||
int32x4_t n;
|
||||
|
||||
r.f = x;
|
||||
n = r.i >> 23;
|
||||
n = n - 127;
|
||||
r.i = r.i - (n << 23);
|
||||
|
||||
*e = n;
|
||||
return r.f;
|
||||
}
|
||||
|
||||
|
||||
__STATIC_INLINE f32x4_t vlogq_f32(f32x4_t vecIn)
|
||||
{
|
||||
q31x4_t vecExpUnBiased;
|
||||
f32x4_t vecTmpFlt0, vecTmpFlt1;
|
||||
f32x4_t vecAcc0, vecAcc1, vecAcc2, vecAcc3;
|
||||
f32x4_t vecExpUnBiasedFlt;
|
||||
|
||||
/*
|
||||
* extract exponent
|
||||
*/
|
||||
vecTmpFlt1 = vmant_exp_f32(vecIn, &vecExpUnBiased);
|
||||
|
||||
vecTmpFlt0 = vecTmpFlt1 * vecTmpFlt1;
|
||||
/*
|
||||
* a = (__logf_lut_f32[4] * r.f) + (__logf_lut_f32[0]);
|
||||
*/
|
||||
vecAcc0 = vdupq_n_f32(__logf_lut_f32[0]);
|
||||
vecAcc0 = vfmaq(vecAcc0, vecTmpFlt1, __logf_lut_f32[4]);
|
||||
/*
|
||||
* b = (__logf_lut_f32[6] * r.f) + (__logf_lut_f32[2]);
|
||||
*/
|
||||
vecAcc1 = vdupq_n_f32(__logf_lut_f32[2]);
|
||||
vecAcc1 = vfmaq(vecAcc1, vecTmpFlt1, __logf_lut_f32[6]);
|
||||
/*
|
||||
* c = (__logf_lut_f32[5] * r.f) + (__logf_lut_f32[1]);
|
||||
*/
|
||||
vecAcc2 = vdupq_n_f32(__logf_lut_f32[1]);
|
||||
vecAcc2 = vfmaq(vecAcc2, vecTmpFlt1, __logf_lut_f32[5]);
|
||||
/*
|
||||
* d = (__logf_lut_f32[7] * r.f) + (__logf_lut_f32[3]);
|
||||
*/
|
||||
vecAcc3 = vdupq_n_f32(__logf_lut_f32[3]);
|
||||
vecAcc3 = vfmaq(vecAcc3, vecTmpFlt1, __logf_lut_f32[7]);
|
||||
/*
|
||||
* a = a + b * xx;
|
||||
*/
|
||||
vecAcc0 = vfmaq(vecAcc0, vecAcc1, vecTmpFlt0);
|
||||
/*
|
||||
* c = c + d * xx;
|
||||
*/
|
||||
vecAcc2 = vfmaq(vecAcc2, vecAcc3, vecTmpFlt0);
|
||||
/*
|
||||
* xx = xx * xx;
|
||||
*/
|
||||
vecTmpFlt0 = vecTmpFlt0 * vecTmpFlt0;
|
||||
vecExpUnBiasedFlt = vcvtq_f32_s32(vecExpUnBiased);
|
||||
/*
|
||||
* r.f = a + c * xx;
|
||||
*/
|
||||
vecAcc0 = vfmaq(vecAcc0, vecAcc2, vecTmpFlt0);
|
||||
/*
|
||||
* add exponent
|
||||
* r.f = r.f + ((float32_t) m) * __logf_rng_f32;
|
||||
*/
|
||||
vecAcc0 = vfmaq(vecAcc0, vecExpUnBiasedFlt, __logf_rng_f32);
|
||||
// set log0 down to -inf
|
||||
vecAcc0 = vdupq_m(vecAcc0, -INFINITY, vcmpeqq(vecIn, 0.0f));
|
||||
return vecAcc0;
|
||||
}
|
||||
|
||||
__STATIC_INLINE f32x4_t vexpq_f32(
|
||||
f32x4_t x)
|
||||
{
|
||||
// Perform range reduction [-log(2),log(2)]
|
||||
int32x4_t m = vcvtq_s32_f32(vmulq_n_f32(x, 1.4426950408f));
|
||||
f32x4_t val = vfmsq_f32(x, vcvtq_f32_s32(m), vdupq_n_f32(0.6931471805f));
|
||||
|
||||
// Polynomial Approximation
|
||||
f32x4_t poly = vtaylor_polyq_f32(val, exp_tab);
|
||||
|
||||
// Reconstruct
|
||||
poly = (f32x4_t) (vqaddq_s32((q31x4_t) (poly), vqshlq_n_s32(m, 23)));
|
||||
|
||||
poly = vdupq_m(poly, 0.0f, vcmpltq_n_s32(m, -126));
|
||||
return poly;
|
||||
}
|
||||
|
||||
__STATIC_INLINE f32x4_t arm_vec_exponent_f32(f32x4_t x, int32_t nb)
|
||||
{
|
||||
f32x4_t r = x;
|
||||
nb--;
|
||||
while (nb > 0) {
|
||||
r = vmulq(r, x);
|
||||
nb--;
|
||||
}
|
||||
return (r);
|
||||
}
|
||||
|
||||
__STATIC_INLINE f32x4_t vrecip_f32(f32x4_t vecIn)
|
||||
{
|
||||
f32x4_t vecSx, vecW, vecTmp;
|
||||
any32x4_t v;
|
||||
|
||||
vecSx = vabsq(vecIn);
|
||||
|
||||
v.f = vecIn;
|
||||
v.i = vsubq(vdupq_n_s32(INV_NEWTON_INIT_F32), v.i);
|
||||
|
||||
vecW = vmulq(vecSx, v.f);
|
||||
|
||||
// v.f = v.f * (8 + w * (-28 + w * (56 + w * (-70 + w *(56 + w * (-28 + w * (8 - w)))))));
|
||||
vecTmp = vsubq(vdupq_n_f32(8.0f), vecW);
|
||||
vecTmp = vfmasq(vecW, vecTmp, -28.0f);
|
||||
vecTmp = vfmasq(vecW, vecTmp, 56.0f);
|
||||
vecTmp = vfmasq(vecW, vecTmp, -70.0f);
|
||||
vecTmp = vfmasq(vecW, vecTmp, 56.0f);
|
||||
vecTmp = vfmasq(vecW, vecTmp, -28.0f);
|
||||
vecTmp = vfmasq(vecW, vecTmp, 8.0f);
|
||||
v.f = vmulq(v.f, vecTmp);
|
||||
|
||||
v.f = vdupq_m(v.f, INFINITY, vcmpeqq(vecIn, 0.0f));
|
||||
/*
|
||||
* restore sign
|
||||
*/
|
||||
v.f = vnegq_m(v.f, v.f, vcmpltq(vecIn, 0.0f));
|
||||
return v.f;
|
||||
}
|
||||
|
||||
__STATIC_INLINE f32x4_t vtanhq_f32(
|
||||
f32x4_t val)
|
||||
{
|
||||
f32x4_t x =
|
||||
vminnmq_f32(vmaxnmq_f32(val, vdupq_n_f32(-10.f)), vdupq_n_f32(10.0f));
|
||||
f32x4_t exp2x = vexpq_f32(vmulq_n_f32(x, 2.f));
|
||||
f32x4_t num = vsubq_n_f32(exp2x, 1.f);
|
||||
f32x4_t den = vaddq_n_f32(exp2x, 1.f);
|
||||
f32x4_t tanh = vmulq_f32(num, vrecip_f32(den));
|
||||
return tanh;
|
||||
}
|
||||
|
||||
__STATIC_INLINE f32x4_t vpowq_f32(
|
||||
f32x4_t val,
|
||||
f32x4_t n)
|
||||
{
|
||||
return vexpq_f32(vmulq_f32(n, vlogq_f32(val)));
|
||||
}
|
||||
|
||||
#endif /* (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE)*/
|
||||
|
||||
#if (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM))
|
||||
#endif /* (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM)) */
|
||||
|
||||
#if (defined(ARM_MATH_NEON) || defined(ARM_MATH_NEON_EXPERIMENTAL)) && !defined(ARM_MATH_AUTOVECTORIZE)
|
||||
|
||||
#include "NEMath.h"
|
||||
/**
|
||||
* @brief Vectorized integer exponentiation
|
||||
* @param[in] x value
|
||||
* @param[in] nb integer exponent >= 1
|
||||
* @return x^nb
|
||||
*
|
||||
*/
|
||||
__STATIC_INLINE float32x4_t arm_vec_exponent_f32(float32x4_t x, int32_t nb)
|
||||
{
|
||||
float32x4_t r = x;
|
||||
nb --;
|
||||
while(nb > 0)
|
||||
{
|
||||
r = vmulq_f32(r , x);
|
||||
nb--;
|
||||
}
|
||||
return(r);
|
||||
}
|
||||
|
||||
|
||||
__STATIC_INLINE float32x4_t __arm_vec_sqrt_f32_neon(float32x4_t x)
|
||||
{
|
||||
float32x4_t x1 = vmaxq_f32(x, vdupq_n_f32(FLT_MIN));
|
||||
float32x4_t e = vrsqrteq_f32(x1);
|
||||
e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x1, e), e), e);
|
||||
e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x1, e), e), e);
|
||||
return vmulq_f32(x, e);
|
||||
}
|
||||
|
||||
__STATIC_INLINE int16x8_t __arm_vec_sqrt_q15_neon(int16x8_t vec)
|
||||
{
|
||||
float32x4_t tempF;
|
||||
int32x4_t tempHI,tempLO;
|
||||
|
||||
tempLO = vmovl_s16(vget_low_s16(vec));
|
||||
tempF = vcvtq_n_f32_s32(tempLO,15);
|
||||
tempF = __arm_vec_sqrt_f32_neon(tempF);
|
||||
tempLO = vcvtq_n_s32_f32(tempF,15);
|
||||
|
||||
tempHI = vmovl_s16(vget_high_s16(vec));
|
||||
tempF = vcvtq_n_f32_s32(tempHI,15);
|
||||
tempF = __arm_vec_sqrt_f32_neon(tempF);
|
||||
tempHI = vcvtq_n_s32_f32(tempF,15);
|
||||
|
||||
return(vcombine_s16(vqmovn_s32(tempLO),vqmovn_s32(tempHI)));
|
||||
}
|
||||
|
||||
__STATIC_INLINE int32x4_t __arm_vec_sqrt_q31_neon(int32x4_t vec)
|
||||
{
|
||||
float32x4_t temp;
|
||||
|
||||
temp = vcvtq_n_f32_s32(vec,31);
|
||||
temp = __arm_vec_sqrt_f32_neon(temp);
|
||||
return(vcvtq_n_s32_f32(temp,31));
|
||||
}
|
||||
|
||||
#endif /* (defined(ARM_MATH_NEON) || defined(ARM_MATH_NEON_EXPERIMENTAL)) && !defined(ARM_MATH_AUTOVECTORIZE) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _ARM_VEC_MATH_H */
|
||||
|
||||
/**
|
||||
*
|
||||
* End of file.
|
||||
*/
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
kernel_module("app_alarm") {
|
||||
sources = [ "app_alarm.c" ]
|
||||
}
|
||||
@@ -0,0 +1,726 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @file app_alarm.c
|
||||
* @author BLE Driver Team
|
||||
* @brief APP Alarm Library.
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
****************************************************************************************
|
||||
*/
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "grx_hal.h"
|
||||
#include "app_alarm.h"
|
||||
|
||||
#ifdef HAL_CALENDAR_MODULE_ENABLED
|
||||
|
||||
/*
|
||||
* DEFINES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
#define _LOCAL_APP_ALARM_LOCK() \
|
||||
uint32_t __l_irq_rest = __get_BASEPRI(); \
|
||||
__set_BASEPRI(NVIC_GetPriority(BLE_IRQn) + \
|
||||
(1 << (NVIC_GetPriorityGrouping() + 1)));
|
||||
|
||||
#define _LOCAL_APP_ALARM_UNLOCK() \
|
||||
__set_BASEPRI(__l_irq_rest);
|
||||
|
||||
#define APP_ALARM_BASE_ALARM_MARK 0x9f00
|
||||
#define APP_ALARM_FIRST_YEAR (2000UL)
|
||||
#define APP_ALARM_SECONDS_PER_HOUR (3600UL)
|
||||
#define APP_ALARM_SECONDS_PER_DAY (24UL * APP_ALARM_SECONDS_PER_HOUR)
|
||||
#define APP_ALARM_SECONDS_PER_YEAR (365UL * APP_ALARM_SECONDS_PER_DAY)
|
||||
#define APP_ALARM_DAYS_PER_MONTH {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
|
||||
#define IS_APP_ALARM_LEAP_YEAR(__YEAR__) ((((__YEAR__) % 4) == 0 && ((__YEAR__) % 100) != 0) || \
|
||||
((__YEAR__) % 400) == 0)
|
||||
|
||||
#define APP_ALARM_LOCK() _LOCAL_APP_ALARM_LOCK()
|
||||
#define APP_ALARM_UNLOCK() _LOCAL_APP_ALARM_UNLOCK()
|
||||
|
||||
/*
|
||||
* STRUCT DEFINE
|
||||
*****************************************************************************************
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
app_alarm_id_t alarm_id;
|
||||
uint32_t delay;
|
||||
app_alarm_t alarm;
|
||||
} app_alarm_node_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
app_alarm_node_t alarm_list[MAX_ALARM_SUPPORT];
|
||||
app_alarm_node_t alarm0;
|
||||
calendar_handle_t handle;
|
||||
bool initialized;
|
||||
uint8_t alarm_available;
|
||||
NvdsTag_t alarm_data_tag;
|
||||
app_alarm_fun_t callback;
|
||||
} app_alarm_info_t;
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DECLARATION
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static uint32_t time2seconds(const app_time_t *time);
|
||||
static void update_alarm_delay(const app_time_t *cur_time, const uint32_t cur_seconds, app_alarm_node_t *alarm_node);
|
||||
static void calendar_alarm_cb(calendar_handle_t *hcalendar);
|
||||
static void sort_alarm_list(void);
|
||||
static uint8_t check_alarm_existed_alarm_id(app_alarm_id_t alarm_id);
|
||||
static uint8_t check_alarm_existed_alarm(const app_alarm_t *alarm);
|
||||
static uint16_t save_alarm_list(void);
|
||||
|
||||
/*
|
||||
* LOCAL VARIABLE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static app_alarm_info_t s_app_alarm_info = {0};
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint16_t app_alarm_init(NvdsTag_t tag, app_alarm_fun_t callback)
|
||||
{
|
||||
hal_status_t hal_err_code;
|
||||
uint8_t error_code;
|
||||
uint16_t len;
|
||||
app_alarm_node_t alarm_buf[MAX_ALARM_SUPPORT];
|
||||
|
||||
if (0xFFFF == tag || 0x0000 == tag || NULL == callback)
|
||||
{
|
||||
return APP_DRV_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
/* Clear rtc_alarm globle info */
|
||||
memset(&s_app_alarm_info, 0, sizeof(app_alarm_info_t));
|
||||
|
||||
/* Initialize calendar */
|
||||
hal_err_code = hal_calendar_init(&s_app_alarm_info.handle);
|
||||
HAL_ERR_CODE_CHECK(hal_err_code);
|
||||
|
||||
/* Copy alarm setting from NVDS to buffer */
|
||||
s_app_alarm_info.alarm_data_tag = tag;
|
||||
s_app_alarm_info.callback = callback;
|
||||
len = sizeof(alarm_buf);
|
||||
error_code = nvds_get(s_app_alarm_info.alarm_data_tag, &len, (uint8_t *)alarm_buf);
|
||||
if (NVDS_SUCCESS != error_code)
|
||||
{
|
||||
if (NVDS_TAG_NOT_EXISTED == error_code)
|
||||
{
|
||||
memset(alarm_buf, 0, sizeof(alarm_buf));
|
||||
error_code = nvds_put(s_app_alarm_info.alarm_data_tag, sizeof(alarm_buf), (const uint8_t *)alarm_buf);
|
||||
if (NVDS_SUCCESS != error_code)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Base alarm, generate an alarm clock at 0 o'clock every day */
|
||||
s_app_alarm_info.alarm0.alarm.hour = 0;
|
||||
s_app_alarm_info.alarm0.alarm.min = 0;
|
||||
s_app_alarm_info.alarm0.alarm.alarm_date_week_mask = 0x7F;
|
||||
s_app_alarm_info.alarm0.alarm.alarm_sel = CALENDAR_ALARM_SEL_WEEKDAY;
|
||||
s_app_alarm_info.alarm0.alarm_id = APP_ALARM_BASE_ALARM_MARK;
|
||||
|
||||
/* Check the number of alarm */
|
||||
for (uint8_t i = 0; i < MAX_ALARM_SUPPORT; i++)
|
||||
{
|
||||
if (alarm_buf[i].alarm.alarm_date_week_mask)
|
||||
{
|
||||
memcpy(&s_app_alarm_info.alarm_list[i], &alarm_buf[i], sizeof(app_alarm_node_t));
|
||||
s_app_alarm_info.alarm_available++;
|
||||
}
|
||||
}
|
||||
|
||||
s_app_alarm_info.initialized = true;
|
||||
|
||||
return APP_DRV_SUCCESS;
|
||||
}
|
||||
|
||||
uint16_t app_alarm_deinit(void)
|
||||
{
|
||||
hal_status_t hal_err_code;
|
||||
uint8_t error_code;
|
||||
|
||||
if (!s_app_alarm_info.initialized)
|
||||
{
|
||||
return APP_DRV_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
hal_err_code = hal_calendar_disable_event(&s_app_alarm_info.handle, CALENDAR_ALARM_DISABLE_ALL);
|
||||
HAL_ERR_CODE_CHECK(hal_err_code);
|
||||
|
||||
hal_err_code = hal_calendar_deinit(&s_app_alarm_info.handle);
|
||||
HAL_ERR_CODE_CHECK(hal_err_code);
|
||||
|
||||
error_code = nvds_del(s_app_alarm_info.alarm_data_tag);
|
||||
if (NVDS_SUCCESS != error_code)
|
||||
{
|
||||
return APP_DRV_ERR_HAL;
|
||||
}
|
||||
|
||||
/* Clear rtc_alarm globle info */
|
||||
memset(&s_app_alarm_info, 0, sizeof(app_alarm_info_t));
|
||||
|
||||
return APP_DRV_SUCCESS;
|
||||
}
|
||||
|
||||
uint16_t app_alarm_add(const app_alarm_t *alarm, app_alarm_id_t p_alarm_id)
|
||||
{
|
||||
hal_status_t hal_err_code;
|
||||
app_drv_err_t app_err_code;
|
||||
|
||||
if (NULL == alarm ||
|
||||
MAX_ALARM_SUPPORT <= s_app_alarm_info.alarm_available ||
|
||||
!s_app_alarm_info.initialized ||
|
||||
APP_ALARM_BASE > p_alarm_id)
|
||||
{
|
||||
return APP_DRV_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
APP_ALARM_LOCK();
|
||||
/* Check the alarm is existed, avoid to load the same alarm */
|
||||
if (check_alarm_existed_alarm(alarm) == s_app_alarm_info.alarm_available)
|
||||
{
|
||||
/* Insert to end */
|
||||
memcpy(&s_app_alarm_info.alarm_list[s_app_alarm_info.alarm_available].alarm, alarm, sizeof(app_alarm_t));
|
||||
s_app_alarm_info.alarm_list[s_app_alarm_info.alarm_available].alarm_id = p_alarm_id ;
|
||||
s_app_alarm_info.alarm_available++;
|
||||
|
||||
/* Sort alarm then set the lastest */
|
||||
sort_alarm_list();
|
||||
if (s_app_alarm_info.alarm0.delay <= s_app_alarm_info.alarm_list[0].delay)
|
||||
{
|
||||
hal_err_code = hal_calendar_set_alarm(&s_app_alarm_info.handle, &s_app_alarm_info.alarm0.alarm);
|
||||
}
|
||||
else
|
||||
{
|
||||
hal_err_code = hal_calendar_set_alarm(&s_app_alarm_info.handle, &s_app_alarm_info.alarm_list[0].alarm);
|
||||
}
|
||||
|
||||
if (HAL_OK != hal_err_code)
|
||||
{
|
||||
APP_ALARM_UNLOCK();
|
||||
return hal_err_code;
|
||||
}
|
||||
|
||||
app_err_code = save_alarm_list();
|
||||
if (APP_DRV_SUCCESS != app_err_code)
|
||||
{
|
||||
APP_ALARM_UNLOCK();
|
||||
return app_err_code;
|
||||
}
|
||||
}
|
||||
APP_ALARM_UNLOCK();
|
||||
|
||||
return APP_DRV_SUCCESS;
|
||||
}
|
||||
|
||||
uint16_t app_alarm_del(app_alarm_id_t alarm_id)
|
||||
{
|
||||
hal_status_t hal_err_code;
|
||||
app_drv_err_t app_err_code;
|
||||
|
||||
if (0 == s_app_alarm_info.alarm_available ||
|
||||
!s_app_alarm_info.initialized ||
|
||||
APP_ALARM_BASE > alarm_id)
|
||||
{
|
||||
return APP_DRV_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
APP_ALARM_LOCK();
|
||||
uint8_t indx = check_alarm_existed_alarm_id(alarm_id);
|
||||
if (indx < s_app_alarm_info.alarm_available)
|
||||
{
|
||||
/* Delete the indx */
|
||||
for (uint8_t i = indx; i < s_app_alarm_info.alarm_available - 1; i++)
|
||||
{
|
||||
memcpy(&s_app_alarm_info.alarm_list[i], &s_app_alarm_info.alarm_list[i + 1], sizeof(app_alarm_node_t));
|
||||
}
|
||||
s_app_alarm_info.alarm_available--;
|
||||
/* Check alarm available, if there is not any alarm then disable alarm */
|
||||
if (s_app_alarm_info.alarm_available > 0)
|
||||
{
|
||||
if (s_app_alarm_info.alarm0.delay <= s_app_alarm_info.alarm_list[0].delay)
|
||||
{
|
||||
hal_err_code = hal_calendar_set_alarm(&s_app_alarm_info.handle, &s_app_alarm_info.alarm0.alarm);
|
||||
}
|
||||
else
|
||||
{
|
||||
hal_err_code = hal_calendar_set_alarm(&s_app_alarm_info.handle, &s_app_alarm_info.alarm_list[0].alarm);
|
||||
}
|
||||
if (HAL_OK != hal_err_code)
|
||||
{
|
||||
APP_ALARM_UNLOCK();
|
||||
return hal_err_code;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hal_err_code = hal_calendar_disable_event(&s_app_alarm_info.handle, CALENDAR_ALARM_DISABLE_ALL);
|
||||
if (HAL_OK != hal_err_code)
|
||||
{
|
||||
APP_ALARM_UNLOCK();
|
||||
return hal_err_code;
|
||||
}
|
||||
}
|
||||
|
||||
app_err_code = save_alarm_list();
|
||||
if (APP_DRV_SUCCESS != app_err_code)
|
||||
{
|
||||
APP_ALARM_UNLOCK();
|
||||
return app_err_code;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
APP_ALARM_UNLOCK();
|
||||
return APP_DRV_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
APP_ALARM_UNLOCK();
|
||||
return APP_DRV_SUCCESS;
|
||||
}
|
||||
|
||||
uint16_t app_alarm_del_all(void)
|
||||
{
|
||||
hal_status_t hal_err_code;
|
||||
app_drv_err_t app_err_code;
|
||||
|
||||
if (0 == s_app_alarm_info.alarm_available ||
|
||||
!s_app_alarm_info.initialized)
|
||||
{
|
||||
return APP_DRV_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
APP_ALARM_LOCK();
|
||||
for (uint8_t i = 0; i < s_app_alarm_info.alarm_available; i++)
|
||||
{
|
||||
memset(&s_app_alarm_info.alarm_list[i], 0, sizeof(app_alarm_node_t));
|
||||
}
|
||||
s_app_alarm_info.alarm_available = 0;
|
||||
hal_err_code = hal_calendar_disable_event(&s_app_alarm_info.handle, CALENDAR_ALARM_DISABLE_ALL);
|
||||
if (HAL_OK != hal_err_code)
|
||||
{
|
||||
APP_ALARM_UNLOCK();
|
||||
return hal_err_code;
|
||||
}
|
||||
|
||||
app_err_code = save_alarm_list();
|
||||
if (APP_DRV_SUCCESS != app_err_code)
|
||||
{
|
||||
APP_ALARM_UNLOCK();
|
||||
return app_err_code;
|
||||
}
|
||||
|
||||
APP_ALARM_UNLOCK();
|
||||
|
||||
return APP_DRV_SUCCESS;
|
||||
}
|
||||
|
||||
uint16_t app_alarm_get_time(app_time_t *p_time)
|
||||
{
|
||||
hal_status_t hal_err_code;
|
||||
|
||||
if (p_time == NULL || !s_app_alarm_info.initialized)
|
||||
{
|
||||
return APP_DRV_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
hal_err_code = hal_calendar_get_time(&s_app_alarm_info.handle, p_time);
|
||||
HAL_ERR_CODE_CHECK(hal_err_code);
|
||||
|
||||
return APP_DRV_SUCCESS;
|
||||
}
|
||||
|
||||
uint16_t app_alarm_set_time(app_time_t *p_time)
|
||||
{
|
||||
hal_status_t hal_err_code;
|
||||
|
||||
if (p_time == NULL || !s_app_alarm_info.initialized)
|
||||
{
|
||||
return APP_DRV_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
hal_err_code = hal_calendar_init_time(&s_app_alarm_info.handle, p_time);
|
||||
HAL_ERR_CODE_CHECK(hal_err_code);
|
||||
|
||||
return APP_DRV_SUCCESS;
|
||||
}
|
||||
|
||||
/* If you reset system time, you should call this function again */
|
||||
uint16_t app_alarm_reload(void)
|
||||
{
|
||||
hal_status_t hal_err_code;
|
||||
|
||||
if (!s_app_alarm_info.initialized)
|
||||
{
|
||||
return APP_DRV_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (0 < s_app_alarm_info.alarm_available)
|
||||
{
|
||||
/* Sort alarm then set the lastest */
|
||||
sort_alarm_list();
|
||||
sys_delay_ms(100);
|
||||
if (s_app_alarm_info.alarm0.delay <= s_app_alarm_info.alarm_list[0].delay)
|
||||
{
|
||||
hal_err_code = hal_calendar_set_alarm(&s_app_alarm_info.handle, &s_app_alarm_info.alarm0.alarm);
|
||||
}
|
||||
else
|
||||
{
|
||||
hal_err_code = hal_calendar_set_alarm(&s_app_alarm_info.handle, &s_app_alarm_info.alarm_list[0].alarm);
|
||||
}
|
||||
HAL_ERR_CODE_CHECK(hal_err_code);
|
||||
}
|
||||
|
||||
return APP_DRV_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
/* Caculate seconds from 01.01.2000 00:00 to the input time */
|
||||
static uint32_t time2seconds(const app_time_t *time)
|
||||
{
|
||||
uint32_t seconds = 0;
|
||||
uint32_t mon_days[12] = APP_ALARM_DAYS_PER_MONTH;
|
||||
|
||||
seconds = time->year * APP_ALARM_SECONDS_PER_YEAR + ((time->year + 3) / 4) * APP_ALARM_SECONDS_PER_DAY;
|
||||
|
||||
mon_days[1] = IS_APP_ALARM_LEAP_YEAR((uint32_t)time->year + APP_ALARM_FIRST_YEAR) ? 29 : 28;
|
||||
for (uint32_t i = 0; i < time->mon - 1; i++)
|
||||
{
|
||||
seconds += mon_days[i] * APP_ALARM_SECONDS_PER_DAY;
|
||||
}
|
||||
|
||||
seconds += (uint32_t)(time->date - 1) * APP_ALARM_SECONDS_PER_DAY;
|
||||
|
||||
seconds += (uint32_t)time->hour * APP_ALARM_SECONDS_PER_HOUR;
|
||||
|
||||
seconds += (uint32_t)time->min * 60 + (uint32_t)time->sec;
|
||||
|
||||
return seconds;
|
||||
}
|
||||
|
||||
/* To caculate how long it will take to get to the alarm time from now */
|
||||
static void update_alarm_delay(const app_time_t *cur_time, const uint32_t cur_seconds, app_alarm_node_t *alarm_node)
|
||||
{
|
||||
uint32_t alarm_sec = 0;
|
||||
uint32_t mon_days[12] = APP_ALARM_DAYS_PER_MONTH;
|
||||
app_time_t time;
|
||||
|
||||
mon_days[1] = IS_APP_ALARM_LEAP_YEAR((uint32_t)cur_time->year + APP_ALARM_FIRST_YEAR) ? 29 : 28;
|
||||
|
||||
memcpy(&time, cur_time, sizeof(app_time_t));
|
||||
/* Set current hour, min and sec to alarm time */
|
||||
time.sec = 0;
|
||||
time.min = alarm_node->alarm.min;
|
||||
time.hour = alarm_node->alarm.hour;
|
||||
if (CALENDAR_ALARM_SEL_DATE == alarm_node->alarm.alarm_sel)
|
||||
{
|
||||
/* Type of alarm is date every month */
|
||||
time.date = alarm_node->alarm.alarm_date_week_mask;
|
||||
alarm_sec = time2seconds(&time);
|
||||
/* Calculate the latest alarm time in the future */
|
||||
if (alarm_sec <= cur_seconds)
|
||||
{
|
||||
if (++time.mon > 12)
|
||||
{
|
||||
time.mon = 1;
|
||||
time.year++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (time.date > mon_days[time.mon - 1])
|
||||
{
|
||||
time.mon++;
|
||||
}
|
||||
}
|
||||
alarm_sec = time2seconds(&time);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Type of alarm is day every week */
|
||||
/* Get the latest date */
|
||||
uint8_t mask = 1 << time.week;
|
||||
do {
|
||||
/* Check if the alarm time is over current time */
|
||||
if (mask & alarm_node->alarm.alarm_date_week_mask)
|
||||
{
|
||||
alarm_sec = time2seconds(&time);
|
||||
if (alarm_sec > cur_seconds)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the next latest alarm time */
|
||||
for (uint8_t day = 1; day < 8; day++)
|
||||
{
|
||||
mask <<= 1;
|
||||
if (0x80 == mask)
|
||||
{
|
||||
mask = CALENDAR_ALARM_WEEKDAY_SUN;
|
||||
}
|
||||
|
||||
if (mask & alarm_node->alarm.alarm_date_week_mask)
|
||||
{
|
||||
time.date += day;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (time.date > mon_days[time.mon - 1])
|
||||
{
|
||||
time.date -= mon_days[time.mon - 1];
|
||||
if (++time.mon > 12)
|
||||
{
|
||||
time.mon = 1;
|
||||
time.year++;
|
||||
}
|
||||
}
|
||||
alarm_sec = time2seconds(&time);
|
||||
} while(0);
|
||||
}
|
||||
|
||||
alarm_node->delay = alarm_sec - cur_seconds;
|
||||
}
|
||||
|
||||
static void calendar_alarm_notify(app_alarm_node_t *alarm_node)
|
||||
{
|
||||
app_time_t time;
|
||||
|
||||
app_alarm_get_time(&time);
|
||||
|
||||
if (time.hour == alarm_node->alarm.hour && time.min == alarm_node->alarm.min)
|
||||
{
|
||||
if (0 == alarm_node->alarm.hour && 0 == alarm_node->alarm.min)
|
||||
{
|
||||
if (CALENDAR_ALARM_SEL_WEEKDAY == alarm_node->alarm.alarm_sel)
|
||||
{
|
||||
if (alarm_node->alarm.alarm_date_week_mask & (1UL << time.week))
|
||||
{
|
||||
s_app_alarm_info.callback(alarm_node->alarm_id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (alarm_node->alarm.alarm_date_week_mask == time.date)
|
||||
{
|
||||
s_app_alarm_info.callback(alarm_node->alarm_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s_app_alarm_info.callback(alarm_node->alarm_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void calendar_alarm_cb(calendar_handle_t *hcalendar)
|
||||
{
|
||||
app_alarm_node_t alarm_node;
|
||||
|
||||
/* Check alarm available */
|
||||
if (0 < s_app_alarm_info.alarm_available)
|
||||
{
|
||||
/* Save the current alarm */
|
||||
memcpy(&alarm_node, &s_app_alarm_info.alarm_list[0], sizeof(app_alarm_node_t));
|
||||
/* Sort for setting next */
|
||||
sort_alarm_list();
|
||||
|
||||
if (s_app_alarm_info.alarm0.delay <= s_app_alarm_info.alarm_list[0].delay)
|
||||
{
|
||||
hal_calendar_set_alarm(&s_app_alarm_info.handle, &s_app_alarm_info.alarm0.alarm);
|
||||
}
|
||||
else
|
||||
{
|
||||
hal_calendar_set_alarm(&s_app_alarm_info.handle, &s_app_alarm_info.alarm_list[0].alarm);
|
||||
}
|
||||
|
||||
/* User callback */
|
||||
calendar_alarm_notify(&alarm_node);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t partition(app_alarm_node_t *alarm_list, int32_t begin, int32_t end)
|
||||
{
|
||||
uint32_t x = alarm_list[end].delay;
|
||||
int32_t i = begin - 1;
|
||||
int32_t j;
|
||||
app_alarm_node_t tmp;
|
||||
|
||||
for (j = begin; j < end; j++)
|
||||
{
|
||||
if (alarm_list[j].delay <= x)
|
||||
{
|
||||
i++;
|
||||
if (j != i)
|
||||
{
|
||||
memcpy(&tmp, &alarm_list[i], sizeof(app_alarm_node_t));
|
||||
memcpy(&alarm_list[i], &alarm_list[j], sizeof(app_alarm_node_t));
|
||||
memcpy(&alarm_list[j], &tmp, sizeof(app_alarm_node_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (++i != end)
|
||||
{
|
||||
memcpy(&tmp, &alarm_list[i], sizeof(app_alarm_node_t));
|
||||
memcpy(&alarm_list[i], &alarm_list[end], sizeof(app_alarm_node_t));
|
||||
memcpy(&alarm_list[end], &tmp, sizeof(app_alarm_node_t));
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void quick_sort(app_alarm_node_t *alarm_list, int32_t begin, int32_t end)
|
||||
{
|
||||
int32_t m = 0;
|
||||
|
||||
if ((NULL == alarm_list) || (begin >= end))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m = partition(alarm_list, begin, end);
|
||||
quick_sort(alarm_list, begin, m - 1);
|
||||
quick_sort(alarm_list, m + 1, end);
|
||||
}
|
||||
|
||||
static void sort_alarm_list(void)
|
||||
{
|
||||
app_time_t cur_time;
|
||||
uint32_t cur_sec;
|
||||
|
||||
if (0 < s_app_alarm_info.alarm_available)
|
||||
{
|
||||
hal_calendar_get_time(&s_app_alarm_info.handle, &cur_time);
|
||||
cur_sec = time2seconds(&cur_time);
|
||||
|
||||
/* Update alarm seconds */
|
||||
for (uint8_t i = 0; i < s_app_alarm_info.alarm_available; i++)
|
||||
{
|
||||
update_alarm_delay(&cur_time, cur_sec, &s_app_alarm_info.alarm_list[i]);
|
||||
}
|
||||
|
||||
/* sort the seconds */
|
||||
quick_sort(s_app_alarm_info.alarm_list, 0, s_app_alarm_info.alarm_available - 1);
|
||||
|
||||
/* update the alarm0 seconds */
|
||||
update_alarm_delay(&cur_time, cur_sec, &s_app_alarm_info.alarm0);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t check_alarm_existed_alarm_id(app_alarm_id_t alarm_id)
|
||||
{
|
||||
uint8_t indx = 0;
|
||||
|
||||
for (; indx < s_app_alarm_info.alarm_available; indx++)
|
||||
{
|
||||
if (s_app_alarm_info.alarm_list[indx].alarm_id == alarm_id)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return indx;
|
||||
}
|
||||
|
||||
static uint8_t check_alarm_existed_alarm(const app_alarm_t *alarm)
|
||||
{
|
||||
uint8_t indx = 0;
|
||||
|
||||
for (; indx < s_app_alarm_info.alarm_available; indx++)
|
||||
{
|
||||
if (!memcmp(&s_app_alarm_info.alarm_list[indx].alarm, alarm, sizeof(app_alarm_t)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return indx;
|
||||
}
|
||||
|
||||
static uint16_t save_alarm_list(void)
|
||||
{
|
||||
uint8_t error_code;
|
||||
app_alarm_node_t alarm_buf[MAX_ALARM_SUPPORT];
|
||||
|
||||
if (!s_app_alarm_info.initialized)
|
||||
{
|
||||
return APP_DRV_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
memset(alarm_buf, 0, sizeof(alarm_buf));
|
||||
for (uint8_t i = 0; i < s_app_alarm_info.alarm_available; i++)
|
||||
{
|
||||
memcpy(&alarm_buf[i], &s_app_alarm_info.alarm_list[i], sizeof(app_alarm_node_t));
|
||||
}
|
||||
|
||||
error_code = nvds_put(s_app_alarm_info.alarm_data_tag, sizeof(alarm_buf), (const uint8_t *)alarm_buf);
|
||||
if (NVDS_SUCCESS != error_code)
|
||||
{
|
||||
return error_code;
|
||||
}
|
||||
|
||||
return APP_DRV_SUCCESS;
|
||||
}
|
||||
|
||||
/* Calendar HAL driver alarm callback */
|
||||
void hal_calendar_alarm_callback(calendar_handle_t *hcalendar)
|
||||
{
|
||||
calendar_alarm_cb(hcalendar);
|
||||
}
|
||||
|
||||
/* Calendar HAL driver overflow callback */
|
||||
void hal_calendar_overflow_callback(calendar_handle_t *hcalendar)
|
||||
{
|
||||
calendar_alarm_cb(hcalendar);
|
||||
}
|
||||
|
||||
void CALENDAR_IRQHandler(void)
|
||||
{
|
||||
hal_calendar_irq_handler(&s_app_alarm_info.handle);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,206 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file app_alarm.h
|
||||
* @author BLE Driver Team
|
||||
* @brief Header file containing functions prototypes of APP Alarm APIs library.
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __APP_ALARM__
|
||||
#define __APP_ALARM__
|
||||
|
||||
#include "grx_sys.h"
|
||||
#include "app_drv_error.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef HAL_CALENDAR_MODULE_ENABLED
|
||||
|
||||
/** @addtogroup APP_ALARM_DEFINES Macro definition
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**@brief APP ALARM tag mask for user application.
|
||||
*/
|
||||
#define APP_ALARM_BASE 0x8000
|
||||
|
||||
/**@brief Get App Alarm tag for user application.
|
||||
*/
|
||||
#define APP_ALARM_ID(idx) (APP_ALARM_BASE | ((idx) & 0x7FFF))
|
||||
|
||||
/**@brief The maximum number of alarms.
|
||||
*/
|
||||
#define MAX_ALARM_SUPPORT 8
|
||||
|
||||
/**@brief App Alarm base year.
|
||||
*/
|
||||
#define APP_ALARM_BASE_YEAR (2000)
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @defgroup APP_ALARM Time
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief App time structure definition
|
||||
*/
|
||||
typedef calendar_time_t app_time_t;
|
||||
|
||||
/**
|
||||
* @brief App alarm structure definition
|
||||
*/
|
||||
typedef calendar_alarm_t app_alarm_t;
|
||||
|
||||
/**
|
||||
* @brief App alarm id definition
|
||||
*/
|
||||
typedef uint16_t app_alarm_id_t;
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup APP_ALARM_STRUCTURES Event definition
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
*@brief The alarm node trigger function.
|
||||
*/
|
||||
typedef void (*app_alarm_fun_t)(app_alarm_id_t app_alarm_id);
|
||||
|
||||
/** @} */
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup APP_ALARM_FUNCTIONS Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize the APP ALARM according to the specified parameters in the
|
||||
* NvdsTag_t where the alram data is stored.
|
||||
*
|
||||
* @param[in] tag: Location where the alram data is stored.
|
||||
* @param[in] callback: Pointer to alarm expire callback function
|
||||
*
|
||||
* @return Result of initialization.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint16_t app_alarm_init(NvdsTag_t tag, app_alarm_fun_t callback);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief De-initialize the app alarm.
|
||||
*
|
||||
* @return Result of De-initialization.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint16_t app_alarm_deinit(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Set a App alarm.
|
||||
*
|
||||
* @note if your call the app_alarm_set_time function,
|
||||
* you should call this function after 1s.
|
||||
*
|
||||
* @param[in] alarm: After seconds will generate an alarm interrupt.
|
||||
* @param[in] alarm_id: the id of alarm node.
|
||||
*
|
||||
* @return Result of operation.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint16_t app_alarm_add(const calendar_alarm_t *alarm, app_alarm_id_t alarm_id);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Delete a App alarm from list.
|
||||
*
|
||||
* @param[in] alarm_id: the id of alarm node.
|
||||
*
|
||||
* @return Result of operation.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint16_t app_alarm_del(app_alarm_id_t alarm_id);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Get current App time.
|
||||
*
|
||||
* @param[in] p_time: Pointer to a app time struction.
|
||||
*
|
||||
* @return Result of operation.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint16_t app_alarm_get_time(calendar_time_t *p_time);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize the app time.
|
||||
*
|
||||
* @param[in] p_time: Pointer to a app time struction.
|
||||
*
|
||||
* @return Result of operation.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint16_t app_alarm_set_time(calendar_time_t *p_time);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Time synchronization function.
|
||||
*
|
||||
* @note If you reset system time, you should call this function again after 1s
|
||||
*
|
||||
* @return Result of operation.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint16_t app_alarm_reload(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Delete all App alarm from list.
|
||||
*
|
||||
* @return Result of operation.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint16_t app_alarm_del_all(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __APP_ALARM__ */
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
kernel_module("app_assert") {
|
||||
sources = [ "app_assert.c" ]
|
||||
}
|
||||
Executable → Regular
+36
-37
@@ -41,12 +41,13 @@
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "app_assert.h"
|
||||
#include "app_log.h"
|
||||
#include <cmsis_compiler.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "app_log.h"
|
||||
#include "app_assert.h"
|
||||
|
||||
|
||||
/*
|
||||
* DEFINITIONS
|
||||
@@ -76,7 +77,8 @@
|
||||
*****************************************************************************************
|
||||
*/
|
||||
/**@brief Assert information save. */
|
||||
struct app_asser_info_t {
|
||||
struct app_asser_info_t
|
||||
{
|
||||
char file_name[APP_ASSERT_FILE_NAME_LEN];
|
||||
int magic1;
|
||||
int file_line;
|
||||
@@ -94,8 +96,9 @@ struct app_asser_info_t {
|
||||
*/
|
||||
static struct app_asser_info_t s_assert_info;
|
||||
|
||||
static sys_assert_cb_t s_assert_cbs = {
|
||||
.assert_err_cb = app_assert_err_cb,
|
||||
static sys_assert_cb_t s_assert_cbs =
|
||||
{
|
||||
.assert_err_cb = app_assert_err_cb ,
|
||||
.assert_param_cb = app_assert_param_cb,
|
||||
.assert_warn_cb = app_assert_warn_cb,
|
||||
};
|
||||
@@ -114,28 +117,21 @@ static sys_assert_cb_t s_assert_cbs = {
|
||||
static void app_assert_info_output(uint8_t assert_type)
|
||||
{
|
||||
char assert_info[1024] = {0};
|
||||
uint32_t ret;
|
||||
|
||||
s_assert_info.file_name[APP_ASSERT_FILE_NAME_LEN - 1] = ' ';
|
||||
s_assert_info.expr[APP_ASSERT_FILE_NAME_LEN - 1] = ' ';
|
||||
|
||||
if (assert_type == APP_ASSERT_ERROR) {
|
||||
ret = sprintf_s(assert_info, sizeof(assert_info), "[ERROR] %s", s_assert_info.expr);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
} else if (assert_type == APP_ASSERT_WARNING) {
|
||||
ret = sprintf_s(assert_info, sizeof(assert_info), "[WARNING] Param0:%d,Param1:%d", s_assert_info.param0,
|
||||
s_assert_info.param1);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
} else if (assert_type == APP_ASSERT_PARAM) {
|
||||
ret = sprintf_s(assert_info, sizeof(assert_info), "[PARAM] Param0:%d,Param1:%d", \
|
||||
s_assert_info.param0, s_assert_info.param1);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
if (APP_ASSERT_ERROR == assert_type)
|
||||
{
|
||||
sprintf(assert_info,"[ERROR] %s", s_assert_info.expr);
|
||||
}
|
||||
else if (APP_ASSERT_WARNING == assert_type)
|
||||
{
|
||||
sprintf(assert_info,"[WARNING] Param0:%d,Param1:%d", s_assert_info.param0, s_assert_info.param1);
|
||||
}
|
||||
else if (APP_ASSERT_PARAM == assert_type)
|
||||
{
|
||||
sprintf(assert_info,"[PARAM] Param0:%d,Param1:%d", s_assert_info.param0, s_assert_info.param1);
|
||||
}
|
||||
|
||||
app_log_output(APP_LOG_LVL_ERROR,
|
||||
@@ -160,8 +156,8 @@ __WEAK void app_assert_warn_cb(int param0, int param1, const char *file, int lin
|
||||
|
||||
file_name_len = (APP_ASSERT_FILE_NAME_LEN < strlen(file)) ? APP_ASSERT_FILE_NAME_LEN : strlen(file);
|
||||
|
||||
memset_s(&s_assert_info, sizeof(s_assert_info), 0, sizeof(s_assert_info));
|
||||
memcpy_s(s_assert_info.file_name, sizeof (s_assert_info.file_name), file, file_name_len);
|
||||
memset(&s_assert_info, 0, sizeof(s_assert_info));
|
||||
memcpy(s_assert_info.file_name, file, file_name_len);
|
||||
|
||||
s_assert_info.magic1 = APP_ASSERT_WARN_MAGIC_1;
|
||||
s_assert_info.file_line = line;
|
||||
@@ -177,14 +173,14 @@ __WEAK void app_assert_warn_cb(int param0, int param1, const char *file, int lin
|
||||
|
||||
__WEAK void app_assert_param_cb(int param0, int param1, const char *file, int line)
|
||||
{
|
||||
__disable_irq();
|
||||
__disable_irq();
|
||||
|
||||
uint32_t file_name_len;
|
||||
|
||||
file_name_len = (APP_ASSERT_FILE_NAME_LEN < strlen(file)) ? APP_ASSERT_FILE_NAME_LEN : strlen(file);
|
||||
|
||||
memset_s(&s_assert_info, sizeof (s_assert_info), 0, sizeof(s_assert_info));
|
||||
memcpy_s(s_assert_info.file_name, sizeof (s_assert_info.file_name), file, file_name_len);
|
||||
memset(&s_assert_info, 0, sizeof(s_assert_info));
|
||||
memcpy(s_assert_info.file_name, file, file_name_len);
|
||||
|
||||
s_assert_info.magic1 = (int)APP_ASSERT_PARAM_MAGIC_1;
|
||||
s_assert_info.file_line = line;
|
||||
@@ -196,13 +192,13 @@ __WEAK void app_assert_param_cb(int param0, int param1, const char *file, int li
|
||||
|
||||
// Also can store assert info to flash
|
||||
app_assert_info_output(APP_ASSERT_PARAM);
|
||||
while (1) {
|
||||
};
|
||||
|
||||
while(1);
|
||||
}
|
||||
|
||||
__WEAK void app_assert_err_cb(const char *expr, const char *file, int line)
|
||||
{
|
||||
__disable_irq();
|
||||
__disable_irq();
|
||||
|
||||
uint32_t file_name_len;
|
||||
uint32_t expre_len;
|
||||
@@ -210,9 +206,10 @@ __WEAK void app_assert_err_cb(const char *expr, const char *file, int line)
|
||||
file_name_len = (APP_ASSERT_FILE_NAME_LEN < strlen(file)) ? APP_ASSERT_FILE_NAME_LEN : strlen(file);
|
||||
expre_len = (APP_ASSERT_EXPR_NAME_LEN < strlen(expr)) ? APP_ASSERT_EXPR_NAME_LEN : strlen(expr);
|
||||
|
||||
memset_s(&s_assert_info, sizeof(s_assert_info), 0, sizeof(s_assert_info));
|
||||
memcpy_s(s_assert_info.file_name, sizeof(s_assert_info.file_name), file, file_name_len);
|
||||
memcpy_s(s_assert_info.expr, sizeof(s_assert_info.expr), expr, expre_len);
|
||||
memset(&s_assert_info, 0, sizeof(s_assert_info));
|
||||
memcpy(s_assert_info.file_name, file, file_name_len);
|
||||
memcpy(s_assert_info.expr, expr, expre_len);
|
||||
|
||||
s_assert_info.magic1 = (int)APP_ASSERT_ERR_MAGIC_1;
|
||||
s_assert_info.file_line = line;
|
||||
s_assert_info.magic2 = (int)APP_ASSERT_ERR_MAGIC_2;
|
||||
@@ -221,8 +218,7 @@ __WEAK void app_assert_err_cb(const char *expr, const char *file, int line)
|
||||
|
||||
// Also can store assert info to flash
|
||||
app_assert_info_output(APP_ASSERT_ERROR);
|
||||
while (1) {
|
||||
};
|
||||
while(1);
|
||||
}
|
||||
|
||||
void app_assert_init(void)
|
||||
@@ -232,7 +228,10 @@ void app_assert_init(void)
|
||||
|
||||
void app_assert_handler(const char *expr, const char *file, int line)
|
||||
{
|
||||
if (s_assert_cbs.assert_err_cb) {
|
||||
if (s_assert_cbs.assert_err_cb)
|
||||
{
|
||||
s_assert_cbs.assert_err_cb(expr, file, line);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Executable → Regular
+8
-3
@@ -38,8 +38,8 @@
|
||||
#ifndef __APP_ASSERT_H__
|
||||
#define __APP_ASSERT_H__
|
||||
|
||||
#include "grx_sys.h"
|
||||
#include <stdint.h>
|
||||
#include "gr55xx_sys.h"
|
||||
|
||||
/**
|
||||
* @defgroup APP_ASSERT_MAROC Defines
|
||||
@@ -53,7 +53,7 @@
|
||||
{ \
|
||||
app_assert_handler(#EXPR, __FILE__, __LINE__); \
|
||||
} \
|
||||
} while (0)
|
||||
} while(0)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@@ -112,6 +112,11 @@ void app_assert_param_cb(int param0, int param1, const char *file, int line);
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_assert_err_cb(const char *expr, const char *file, int line);
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
kernel_module("app_error") {
|
||||
sources = [
|
||||
"app_error.c",
|
||||
"cortex_backtrace.c",
|
||||
]
|
||||
}
|
||||
Executable → Regular
+35
-33
@@ -41,26 +41,27 @@
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "app_error.h"
|
||||
#include "app_error_cfg.h"
|
||||
#include "app_log.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "app_error_cfg.h"
|
||||
#include "app_log.h"
|
||||
#include "app_error.h"
|
||||
|
||||
/*
|
||||
* DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#define APP_ERROR_INFO_LEN 512
|
||||
#define APP_ERROR_CODE_NB 43
|
||||
#define APP_ERROR_CODE_NB 46
|
||||
|
||||
/*
|
||||
* STRUCTURES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
/**@brief SDK error code information. */
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
sdk_err_t error_code;
|
||||
char *error_info;
|
||||
} error_code_info_t;
|
||||
@@ -69,8 +70,10 @@ typedef struct {
|
||||
* LOCAL VARIABLE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#ifndef GR5515_E
|
||||
static error_code_info_t s_error_code_info[APP_ERROR_CODE_NB] = {
|
||||
static char s_error_print_info[APP_ERROR_INFO_LEN] = { 0 };
|
||||
|
||||
static error_code_info_t s_error_code_info[APP_ERROR_CODE_NB] =
|
||||
{
|
||||
{SDK_SUCCESS, "Successful."},
|
||||
{SDK_ERR_INVALID_PARAM, "Invalid parameter supplied."},
|
||||
{SDK_ERR_POINTER_NULL, "Invalid pointer supplied."},
|
||||
@@ -114,10 +117,11 @@ static error_code_info_t s_error_code_info[APP_ERROR_CODE_NB] = {
|
||||
{SDK_ERR_INVALID_CID, "Invalid CID supplied."},
|
||||
{SDK_ERR_INVALID_CHL_NUM, "Invalid channel number supplied."},
|
||||
{SDK_ERR_NOT_ENOUGH_CREDITS, "Not enough credits."},
|
||||
{SDK_ERR_REPEAT_CID, "Invalid repeat CID."},
|
||||
{SDK_ERR_CACHE_NOT_ENABLE, "Cache feature is not enabled."},
|
||||
{SDK_ERR_CACHE_INVALID, "Cache data is invalid."},
|
||||
};
|
||||
#else
|
||||
static error_code_info_t s_error_code_info[];
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
@@ -126,36 +130,34 @@ static error_code_info_t s_error_code_info[];
|
||||
__WEAK void app_error_fault_handler(app_error_info_t *p_error_info)
|
||||
{
|
||||
#if APP_ERROR_INFO_PRINT_ENABLE
|
||||
uint32_t ret;
|
||||
char s_error_print_info[APP_ERROR_INFO_LEN];
|
||||
ret = memset_s(s_error_print_info, sizeof(s_error_print_info), 0, APP_ERROR_INFO_LEN);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
memset(s_error_print_info, 0, APP_ERROR_INFO_LEN);
|
||||
|
||||
if (APP_ERROR_API_RET == p_error_info->error_type) {
|
||||
for (uint8_t i = 0; ; i++) {
|
||||
if (p_error_info->value.error_code == s_error_code_info[i].error_code) {
|
||||
ret = sprintf_s(s_error_print_info, sizeof (s_error_print_info),
|
||||
"Error code 0x%04X: %s",
|
||||
p_error_info->value.error_code,
|
||||
s_error_code_info[i].error_info);
|
||||
if (APP_ERROR_API_RET == p_error_info->error_type)
|
||||
{
|
||||
for (uint8_t i = 0; ; i++)
|
||||
{
|
||||
if (p_error_info->value.error_code == s_error_code_info[i].error_code)
|
||||
{
|
||||
sprintf(s_error_print_info,
|
||||
"Error code 0x%04X: %s",
|
||||
p_error_info->value.error_code,
|
||||
s_error_code_info[i].error_info);
|
||||
break;
|
||||
} else if (i == APP_ERROR_CODE_NB) {
|
||||
ret = sprintf_s(s_error_print_info, sizeof(s_error_print_info), \
|
||||
"Error code 0x%04X: No found information.", p_error_info->value.error_code);
|
||||
}
|
||||
else if (APP_ERROR_CODE_NB == i)
|
||||
{
|
||||
sprintf(s_error_print_info, "Error code 0x%04X: No found information.", p_error_info->value.error_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (APP_ERROR_BOOL_COMPARE == p_error_info->error_type) {
|
||||
ret = sprintf_s(s_error_print_info, sizeof(s_error_print_info),
|
||||
"(%s) is not established.",
|
||||
p_error_info->value.expr);
|
||||
}
|
||||
else if (APP_ERROR_BOOL_COMPARE == p_error_info->error_type)
|
||||
{
|
||||
sprintf(s_error_print_info,
|
||||
"(%s) is not established.",
|
||||
p_error_info->value.expr);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
app_log_output(APP_LOG_LVL_ERROR,
|
||||
APP_LOG_TAG,
|
||||
p_error_info->file,
|
||||
|
||||
Executable → Regular
+25
-15
@@ -38,8 +38,8 @@
|
||||
#ifndef __APP_ERROR_H__
|
||||
#define __APP_ERROR_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ble_error.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @defgroup APP_ERROR_MAROC Defines
|
||||
@@ -48,32 +48,39 @@
|
||||
|
||||
/**@brief Macro for calling error handler function if supplied error code isn`t GR_SUCCESS. */
|
||||
#define APP_ERROR_CHECK(ERROR_CODE) \
|
||||
do { \
|
||||
if ((ERROR_CODE) != SDK_SUCCESS) { \
|
||||
app_error_info_t error_info = { \
|
||||
do \
|
||||
{ \
|
||||
if (ERROR_CODE != SDK_SUCCESS) \
|
||||
{ \
|
||||
app_error_info_t error_info = \
|
||||
{ \
|
||||
.error_type = APP_ERROR_API_RET, \
|
||||
.value.error_code = (ERROR_CODE), \
|
||||
.value.error_code = ERROR_CODE, \
|
||||
.file = __FILE__, \
|
||||
.func = __FUNCTION__, \
|
||||
.line = __LINE__, \
|
||||
}; \
|
||||
app_error_fault_handler(&error_info); \
|
||||
} \
|
||||
} while (0)
|
||||
} while(0)
|
||||
|
||||
/**@brief Macro for calling error handler function if supplied boolean value is false. */
|
||||
#define APP_BOOL_CHECK(BOOL_VAL) \
|
||||
do { \
|
||||
if (!(BOOL_VAL)) { \
|
||||
app_error_info_t error_info = { \
|
||||
do \
|
||||
{ \
|
||||
if (!BOOL_VAL) \
|
||||
{ \
|
||||
app_error_info_t error_info = \
|
||||
{ \
|
||||
.error_type = APP_ERROR_BOOL_COMPARE, \
|
||||
.value.expr = #BOOL_VAL, \
|
||||
.file = __FILE__, \
|
||||
.func = __FUNCTION__, .line = __LINE__, \
|
||||
.file = __FILE__, \
|
||||
.func = __FUNCTION__, \
|
||||
.line = __LINE__, \
|
||||
}; \
|
||||
app_error_fault_handler(&error_info); \
|
||||
} \
|
||||
} while (0)
|
||||
} while(0)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@@ -81,7 +88,8 @@
|
||||
* @{
|
||||
*/
|
||||
/**@brief App error check type.*/
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
APP_ERROR_API_RET, /**< API return error code check failed. */
|
||||
APP_ERROR_BOOL_COMPARE, /**< Bool value check failed. */
|
||||
} app_error_type_t;
|
||||
@@ -92,9 +100,11 @@ typedef enum {
|
||||
* @{
|
||||
*/
|
||||
/**@brief App error info.*/
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
app_error_type_t error_type; /**< Error occurred type. */
|
||||
union {
|
||||
union
|
||||
{
|
||||
sdk_err_t error_code; /**< Error code. */
|
||||
char const *expr; /**< Error expression. */
|
||||
} value;
|
||||
|
||||
Executable → Regular
+9
-11
@@ -38,10 +38,10 @@
|
||||
#ifndef __APP_ERROR_CFG_H__
|
||||
#define __APP_ERROR_CFG_H__
|
||||
|
||||
#include "grx_sys.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "gr55xx.h"
|
||||
|
||||
/**
|
||||
* @defgroup APP_ERROR_CFG_MAROC Defines
|
||||
@@ -49,22 +49,20 @@
|
||||
*/
|
||||
#define APP_IS_USING_FREEROTS false /**< Is using FREEROTS or not. */
|
||||
#define APP_ERROR_DUMP_STACK_INFO_ENABLE 1 /**< Enable dump stack information. */
|
||||
/**< Enable error information prinf. */
|
||||
#define APP_ERROR_INFO_PRINT_ENABLE 1
|
||||
/**< Supported function call stack max depth, default is 16. */
|
||||
#define APP_ERROR_CALL_STACK_DEPTH_MAX 16
|
||||
#define APP_ERROR_INFO_PRINT_ENABLE 1 /**< Enable error information prinf. */
|
||||
#define APP_ERROR_CALL_STACK_DEPTH_MAX 16 /**< Supported function call stack max depth, default is 16. */
|
||||
|
||||
#if APP_ERROR_INFO_PRINT_ENABLE
|
||||
#define APP_ERROR_INFO_PRINT(...) printf(__VA_ARGS__);printf("\r\n") /**< Print line. */
|
||||
#define APP_ERROR_INFO_PRINT(...) printf(__VA_ARGS__);printf("\r\n");/**< Print line. */
|
||||
#else
|
||||
#define APP_ERROR_INFO_PRINT(...)
|
||||
#define APP_ERROR_INFO_PRINT(...)
|
||||
#endif
|
||||
|
||||
#if APP_IS_USING_FREEROTS
|
||||
#include "FreeRTOS.h"
|
||||
extern uint32_t *vTaskStackAddr(void);
|
||||
extern uint32_t vTaskStackSize(void);
|
||||
extern char *vTaskName(void);
|
||||
#include "FreeRTOS.h"
|
||||
extern uint32_t *vTaskStackAddr(void);
|
||||
extern uint32_t vTaskStackSize(void);
|
||||
extern char *vTaskName(void);
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
Executable → Regular
+574
-512
File diff suppressed because it is too large
Load Diff
Executable → Regular
+131
-196
@@ -38,71 +38,8 @@
|
||||
#ifndef __CORTEX_BACKTRACE_H__
|
||||
#define __CORTEX_BACKTRACE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "app_error_cfg.h"
|
||||
|
||||
#if ENABLE_BACKTRACE_FEASS
|
||||
#define TWO 2
|
||||
#define FOUR 4
|
||||
#define LEFT_MOV_2BIT 2
|
||||
#define REGISTER_CNT 8
|
||||
#define DRG_R0 0
|
||||
#define DRG_R1 1
|
||||
#define DRG_R2 2
|
||||
#define DRG_R3 3
|
||||
#define DRG_R4 4
|
||||
#define DRG_R5 5
|
||||
#define DRG_R6 6
|
||||
#define DRG_R7 7
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
#define CSTACK_BLOCK_NAME ARM_LIB_STACKHEAP /**< C stack block name: ARM_LIB_STACKHEAP. */
|
||||
#define CODE_SECTION_NAME FLASH_CODE /**< Code section name: ER_FLASH. */
|
||||
|
||||
#define SECTION_START(_name_) _name_##$$Base
|
||||
#define SECTION_END(_name_) _name_##$$Limit
|
||||
#define IMAGE_SECTION_START(_name_) Image$$##_name_##$$Base
|
||||
#define IMAGE_SECTION_END(_name_) Image$$##_name_##$$ZI$$Limit
|
||||
#define CSTACK_BLOCK_START(_name_) IMAGE_SECTION_START(_name_)
|
||||
#define CSTACK_BLOCK_END(_name_) IMAGE_SECTION_END(_name_)
|
||||
#define CODE_SECTION_START(_name_) IMAGE_SECTION_START(_name_)
|
||||
#define CODE_SECTION_END(_name_) IMAGE_SECTION_END(_name_)
|
||||
|
||||
extern const int CSTACK_BLOCK_START(CSTACK_BLOCK_NAME);
|
||||
extern const int CSTACK_BLOCK_END(CSTACK_BLOCK_NAME);
|
||||
extern const int CODE_SECTION_START(CODE_SECTION_NAME);
|
||||
extern const int CODE_SECTION_END(CODE_SECTION_NAME);
|
||||
#elif defined(__ICCARM__)
|
||||
#define CSTACK_BLOCK_NAME "CSTACK" /**< C stack block name, default is 'CSTACK'. */
|
||||
#define CODE_SECTION_NAME ".text" /**< Code section name, default is '.text'. */
|
||||
|
||||
#pragma section = CMB_CSTACK_BLOCK_NAME
|
||||
#pragma section = CMB_CODE_SECTION_NAME
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
/**< C stack block start address, defined on linker script file, default is _sstack. */
|
||||
#define CSTACK_BLOCK_START _sstack
|
||||
/**< C stack block end address, defined on linker script file, default is _estack. */
|
||||
#define CSTACK_BLOCK_END _estack
|
||||
/**< code section start address, defined on linker script file, default is _stext. */
|
||||
#define CODE_SECTION_START _stext
|
||||
/**< code section end address, defined on linker script file, default is _etext. */
|
||||
#define CODE_SECTION_END _etext
|
||||
#define CALLBACK_CNT 9
|
||||
#define ZERO 0
|
||||
|
||||
extern const int CSTACK_BLOCK_START;
|
||||
extern const int CSTACK_BLOCK_END;
|
||||
extern const int CODE_SECTION_START;
|
||||
extern const int CODE_SECTION_END;
|
||||
#else
|
||||
#error "not supported compiler"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void fault_trace_nvds_save_prepare(void);
|
||||
void fault_trace_nvds_add(const char *format, ...);
|
||||
void fault_trace_nvds_save_flush(void);
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @defgroup CORTEX_BACKTRACE_MAROC Defines
|
||||
@@ -113,34 +50,25 @@ void fault_trace_nvds_save_flush(void);
|
||||
#define CB_CPU_ARM_CORTEX_M4 (0x04U) /**< Cortex-M4 Core */
|
||||
#define CB_CPU_ARM_CORTEX_M7 (0x07U) /**< Cortex-M7 Core */
|
||||
|
||||
/**< System Handler Control and State Register.*/
|
||||
#define CB_SYSHND_CTRL (*(volatile unsigned int*) (0xE000ED24u))
|
||||
/**< Memory management fault State register. */
|
||||
#define CB_NVIC_MFSR (*(volatile unsigned char*) (0xE000ED28u))
|
||||
/**< Bus fault State register. */
|
||||
#define CB_NVIC_BFSR (*(volatile unsigned char*) (0xE000ED29u))
|
||||
/**< Usage fault State register. */
|
||||
#define CB_NVIC_UFSR (*(volatile unsigned short*)(0xE000ED2Au))
|
||||
/**< Hard fault State register. */
|
||||
#define CB_NVIC_HFSR (*(volatile unsigned int*) (0xE000ED2Cu))
|
||||
/**< Debug fault State register. */
|
||||
#define CB_NVIC_DFSR (*(volatile unsigned short*)(0xE000ED30u))
|
||||
/**< Memory management fault address register. */
|
||||
#define CB_NVIC_MMAR (*(volatile unsigned int*) (0xE000ED34u))
|
||||
/**< Bus fault manage address register. */
|
||||
#define CB_NVIC_BFAR (*(volatile unsigned int*) (0xE000ED38u))
|
||||
/**< Auxiliary fault State register. */
|
||||
#define CB_NVIC_AFSR (*(volatile unsigned short*)(0xE000ED3Cu))
|
||||
#define CB_SYSHND_CTRL (*(volatile unsigned int*) (0xE000ED24u)) /**< System Handler Control and State Register. */
|
||||
#define CB_NVIC_MFSR (*(volatile unsigned char*) (0xE000ED28u)) /**< Memory management fault State register. */
|
||||
#define CB_NVIC_BFSR (*(volatile unsigned char*) (0xE000ED29u)) /**< Bus fault State register. */
|
||||
#define CB_NVIC_UFSR (*(volatile unsigned short*)(0xE000ED2Au)) /**< Usage fault State register. */
|
||||
#define CB_NVIC_HFSR (*(volatile unsigned int*) (0xE000ED2Cu)) /**< Hard fault State register. */
|
||||
#define CB_NVIC_DFSR (*(volatile unsigned short*)(0xE000ED30u)) /**< Debug fault State register. */
|
||||
#define CB_NVIC_MMAR (*(volatile unsigned int*) (0xE000ED34u)) /**< Memory management fault address register. */
|
||||
#define CB_NVIC_BFAR (*(volatile unsigned int*) (0xE000ED38u)) /**< Bus fault manage address register. */
|
||||
#define CB_NVIC_AFSR (*(volatile unsigned short*)(0xE000ED3Cu)) /**< Auxiliary fault State register. */
|
||||
|
||||
/**@brief ELF(Executable and Linking Format) file extension name for each compiler. */
|
||||
#if defined(__CC_ARM)
|
||||
#define CB_ELF_FILE_EXTENSION_NAME ".axf"
|
||||
#define CB_ELF_FILE_EXTENSION_NAME ".axf"
|
||||
#elif defined(__ICCARM__)
|
||||
#define CB_ELF_FILE_EXTENSION_NAME ".out"
|
||||
#define CB_ELF_FILE_EXTENSION_NAME ".out"
|
||||
#elif defined(__GNUC__)
|
||||
#define CB_ELF_FILE_EXTENSION_NAME ".elf"
|
||||
#define CB_ELF_FILE_EXTENSION_NAME ".elf"
|
||||
#else
|
||||
#error "not supported compiler"
|
||||
#error "not supported compiler"
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
@@ -149,123 +77,130 @@ void fault_trace_nvds_save_flush(void);
|
||||
* @{
|
||||
*/
|
||||
/**@brief Cortex-M fault registers. */
|
||||
typedef struct {
|
||||
struct {
|
||||
unsigned int r0; /**< Register R0. */
|
||||
unsigned int r1; /**< Register R1. */
|
||||
unsigned int r2; /**< Register R2. */
|
||||
unsigned int r3; /**< Register R3. */
|
||||
unsigned int r12; /**< Register R12. */
|
||||
unsigned int lr; /**< Link register. */
|
||||
unsigned int pc; /**< Program counter. */
|
||||
union {
|
||||
unsigned int value;
|
||||
struct {
|
||||
unsigned int IPSR : 8; /**< Interrupt Program Status register (IPSR). */
|
||||
unsigned int EPSR : 19; /**< Execution Program Status register (EPSR). */
|
||||
unsigned int APSR : 5; /**< Application Program Status register (APSR). */
|
||||
} bits;
|
||||
} psr; /**< Program status register. */
|
||||
} saved;
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned int r0; /**< Register R0. */
|
||||
unsigned int r1; /**< Register R1. */
|
||||
unsigned int r2; /**< Register R2. */
|
||||
unsigned int r3; /**< Register R3. */
|
||||
unsigned int r12; /**< Register R12. */
|
||||
unsigned int lr; /**< Link register. */
|
||||
unsigned int pc; /**< Program counter. */
|
||||
union
|
||||
{
|
||||
unsigned int value;
|
||||
struct
|
||||
{
|
||||
unsigned int IPSR : 8; /**< Interrupt Program Status register (IPSR). */
|
||||
unsigned int EPSR : 19; /**< Execution Program Status register (EPSR). */
|
||||
unsigned int APSR : 5; /**< Application Program Status register (APSR). */
|
||||
} bits;
|
||||
} psr; /**< Program status register. */
|
||||
} saved;
|
||||
|
||||
union {
|
||||
unsigned int value;
|
||||
struct {
|
||||
unsigned int MEMFAULTACT : 1; /**< Read as 1 if memory management fault is active. */
|
||||
unsigned int BUSFAULTACT : 1; /**< Read as 1 if bus fault exception is active. */
|
||||
unsigned int UnusedBits1 : 1; /**< Unused Bits 1. */
|
||||
unsigned int USGFAULTACT : 1; /**< Read as 1 if usage fault exception is active. */
|
||||
unsigned int UnusedBits2 : 3; /**< Unused Bits 2. */
|
||||
unsigned int SVCALLACT : 1; /**< Read as 1 if SVC exception is active. */
|
||||
unsigned int MONITORACT : 1; /**< Read as 1 if debug monitor exception is active. */
|
||||
unsigned int UnusedBits3 : 1; /**< Unused Bits 3. */
|
||||
unsigned int PENDSVACT : 1; /**< Read as 1 if PendSV exception is active. */
|
||||
unsigned int SYSTICKACT : 1; /**< Read as 1 if SYSTICK exception is active. */
|
||||
/**< Usage fault pended; usage fault started but was replaced by a higher-priority exception. */
|
||||
unsigned int USGFAULTPENDED : 1;
|
||||
/**< Memory management fault pended; memory management fault started but was replaced
|
||||
* by a higher-priority exception. */
|
||||
unsigned int MEMFAULTPENDED : 1;
|
||||
/**< Bus fault pended; bus fault handler was started but was replaced by a higher-priority exception. */
|
||||
unsigned int BUSFAULTPENDED : 1;
|
||||
/**< SVC pended; SVC was started but was replaced by a higher-priority exception. */
|
||||
unsigned int SVCALLPENDED : 1;
|
||||
unsigned int MEMFAULTENA : 1; /**< Memory management fault handler enable. */
|
||||
unsigned int BUSFAULTENA : 1; /**< Bus fault handler enable. */
|
||||
unsigned int USGFAULTENA : 1; /**< Usage fault handler enable. */
|
||||
} bits;
|
||||
} syshndctrl; /**< System Handler Control and State Register (0xE000ED24). */
|
||||
union
|
||||
{
|
||||
unsigned int value;
|
||||
struct
|
||||
{
|
||||
unsigned int MEMFAULTACT : 1; /**< Read as 1 if memory management fault is active. */
|
||||
unsigned int BUSFAULTACT : 1; /**< Read as 1 if bus fault exception is active. */
|
||||
unsigned int UnusedBits1 : 1; /**< Unused Bits 1. */
|
||||
unsigned int USGFAULTACT : 1; /**< Read as 1 if usage fault exception is active. */
|
||||
unsigned int UnusedBits2 : 3; /**< Unused Bits 2. */
|
||||
unsigned int SVCALLACT : 1; /**< Read as 1 if SVC exception is active. */
|
||||
unsigned int MONITORACT : 1; /**< Read as 1 if debug monitor exception is active. */
|
||||
unsigned int UnusedBits3 : 1; /**< Unused Bits 3. */
|
||||
unsigned int PENDSVACT : 1; /**< Read as 1 if PendSV exception is active. */
|
||||
unsigned int SYSTICKACT : 1; /**< Read as 1 if SYSTICK exception is active. */
|
||||
unsigned int USGFAULTPENDED : 1; /**< Usage fault pended; usage fault started but was replaced by a higher-priority exception. */
|
||||
unsigned int MEMFAULTPENDED : 1; /**< Memory management fault pended; memory management fault started but was replaced by a higher-priority exception. */
|
||||
unsigned int BUSFAULTPENDED : 1; /**< Bus fault pended; bus fault handler was started but was replaced by a higher-priority exception. */
|
||||
unsigned int SVCALLPENDED : 1; /**< SVC pended; SVC was started but was replaced by a higher-priority exception. */
|
||||
unsigned int MEMFAULTENA : 1; /**< Memory management fault handler enable. */
|
||||
unsigned int BUSFAULTENA : 1; /**< Bus fault handler enable. */
|
||||
unsigned int USGFAULTENA : 1; /**< Usage fault handler enable. */
|
||||
} bits;
|
||||
} syshndctrl; /**< System Handler Control and State Register (0xE000ED24). */
|
||||
|
||||
union {
|
||||
unsigned char value;
|
||||
struct {
|
||||
unsigned char IACCVIOL : 1; /**< Instruction access violation. */
|
||||
unsigned char DACCVIOL : 1; /**< Data access violation. */
|
||||
unsigned char UnusedBits : 1; /**< Unused Bits 1. */
|
||||
unsigned char MUNSTKERR : 1; /**< Unstacking error. */
|
||||
unsigned char MSTKERR : 1; /**< Stacking error. */
|
||||
unsigned char MLSPERR : 1; /**< Floating-point lazy state preservation (M4/M7). */
|
||||
unsigned char UnusedBits2 : 1; /**< Unused Bits 2. */
|
||||
unsigned char MMARVALID : 1; /**< Indicates the MMAR is valid. */
|
||||
} bits;
|
||||
} mfsr; /**< Memory Management Fault Status Register (0xE000ED28). */
|
||||
unsigned int mmar; /**< Memory Management Fault Address Register (0xE000ED34). */
|
||||
union
|
||||
{
|
||||
unsigned char value;
|
||||
struct
|
||||
{
|
||||
unsigned char IACCVIOL : 1; /**< Instruction access violation. */
|
||||
unsigned char DACCVIOL : 1; /**< Data access violation. */
|
||||
unsigned char UnusedBits : 1; /**< Unused Bits 1. */
|
||||
unsigned char MUNSTKERR : 1; /**< Unstacking error. */
|
||||
unsigned char MSTKERR : 1; /**< Stacking error. */
|
||||
unsigned char MLSPERR : 1; /**< Floating-point lazy state preservation (M4/M7). */
|
||||
unsigned char UnusedBits2 : 1; /**< Unused Bits 2. */
|
||||
unsigned char MMARVALID : 1; /**< Indicates the MMAR is valid. */
|
||||
} bits;
|
||||
} mfsr; /**< Memory Management Fault Status Register (0xE000ED28). */
|
||||
unsigned int mmar; /**< Memory Management Fault Address Register (0xE000ED34). */
|
||||
|
||||
union {
|
||||
unsigned char value;
|
||||
struct {
|
||||
unsigned char IBUSERR : 1; /**< Instruction access violation. */
|
||||
unsigned char PRECISERR : 1; /**< Precise data access violation. */
|
||||
unsigned char IMPREISERR : 1; /**< Imprecise data access violation. */
|
||||
unsigned char UNSTKERR : 1; /**< Unstacking error. */
|
||||
unsigned char STKERR : 1; /**< Stacking error. */
|
||||
unsigned char LSPERR : 1; /**< Floating-point lazy state preservation (M4/M7). */
|
||||
unsigned char UnusedBits : 1; /**< Unused Bits 1. */
|
||||
unsigned char BFARVALID : 1; /**< Indicates BFAR is valid. */
|
||||
} bits;
|
||||
} bfsr; /**< Bus Fault Status Register (0xE000ED29). */
|
||||
unsigned int bfar; /**< Bus Fault Manage Address Register (0xE000ED38). */
|
||||
union
|
||||
{
|
||||
unsigned char value;
|
||||
struct
|
||||
{
|
||||
unsigned char IBUSERR : 1; /**< Instruction access violation. */
|
||||
unsigned char PRECISERR : 1; /**< Precise data access violation. */
|
||||
unsigned char IMPREISERR : 1; /**< Imprecise data access violation. */
|
||||
unsigned char UNSTKERR : 1; /**< Unstacking error. */
|
||||
unsigned char STKERR : 1; /**< Stacking error. */
|
||||
unsigned char LSPERR : 1; /**< Floating-point lazy state preservation (M4/M7). */
|
||||
unsigned char UnusedBits : 1; /**< Unused Bits 1. */
|
||||
unsigned char BFARVALID : 1; /**< Indicates BFAR is valid. */
|
||||
} bits;
|
||||
} bfsr; /**< Bus Fault Status Register (0xE000ED29). */
|
||||
unsigned int bfar; /**< Bus Fault Manage Address Register (0xE000ED38). */
|
||||
|
||||
union {
|
||||
unsigned short value;
|
||||
struct {
|
||||
unsigned short UNDEFINSTR : 1; /**< Attempts to execute an undefined instruction. */
|
||||
unsigned short INVSTATE : 1; /**< Attempts to switch to an invalid state (e.g., ARM). */
|
||||
/**< Attempts to do an exception with a bad value in the EXC_RETURN number. */
|
||||
unsigned short INVPC : 1;
|
||||
unsigned short NOCP : 1; /**< Attempts to execute a coprocessor instruction. */
|
||||
unsigned short UnusedBits : 4; /**< Unused Bits 1. */
|
||||
unsigned short UNALIGNED : 1; /**< Indicates that an unaligned access fault has taken place. */
|
||||
unsigned short DIVBYZERO0 :
|
||||
1; /**< Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set). */
|
||||
} bits;
|
||||
} ufsr; /**< Usage Fault Status Register (0xE000ED2A). */
|
||||
union
|
||||
{
|
||||
unsigned short value;
|
||||
struct
|
||||
{
|
||||
unsigned short UNDEFINSTR : 1; /**< Attempts to execute an undefined instruction. */
|
||||
unsigned short INVSTATE : 1; /**< Attempts to switch to an invalid state (e.g., ARM). */
|
||||
unsigned short INVPC : 1; /**< Attempts to do an exception with a bad value in the EXC_RETURN number. */
|
||||
unsigned short NOCP : 1; /**< Attempts to execute a coprocessor instruction. */
|
||||
unsigned short UnusedBits : 4; /**< Unused Bits 1. */
|
||||
unsigned short UNALIGNED : 1; /**< Indicates that an unaligned access fault has taken place. */
|
||||
unsigned short DIVBYZERO0 : 1; /**< Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set). */
|
||||
} bits;
|
||||
} ufsr; /**< Usage Fault Status Register (0xE000ED2A). */
|
||||
|
||||
union {
|
||||
unsigned int value;
|
||||
struct {
|
||||
unsigned int UnusedBits : 1;
|
||||
unsigned int VECTBL : 1; /**< Indicates hard fault is caused by failed vector fetch. */
|
||||
unsigned int UnusedBits2 : 28; /**< Unused Bits 1. */
|
||||
unsigned int FORCED :
|
||||
1; /**< Indicates hard fault is taken because of bus fault/memory management fault/usage fault. */
|
||||
unsigned int DEBUGEVT : 1; /**< Indicates hard fault is triggered by debug event. */
|
||||
} bits;
|
||||
} hfsr; /**< Hard Fault Status Register (0xE000ED2C). */
|
||||
union
|
||||
{
|
||||
unsigned int value;
|
||||
struct
|
||||
{
|
||||
unsigned int UnusedBits : 1;
|
||||
unsigned int VECTBL : 1; /**< Indicates hard fault is caused by failed vector fetch. */
|
||||
unsigned int UnusedBits2 : 28; /**< Unused Bits 1. */
|
||||
unsigned int FORCED : 1; /**< Indicates hard fault is taken because of bus fault/memory management fault/usage fault. */
|
||||
unsigned int DEBUGEVT : 1; /**< Indicates hard fault is triggered by debug event. */
|
||||
} bits;
|
||||
} hfsr; /**< Hard Fault Status Register (0xE000ED2C). */
|
||||
|
||||
union {
|
||||
unsigned int value;
|
||||
struct {
|
||||
unsigned int HALTED : 1; /**< Halt requested in NVIC. */
|
||||
unsigned int BKPT : 1; /**< BKPT instruction executed. */
|
||||
unsigned int DWTTRAP : 1; /**< DWT match occurred. */
|
||||
unsigned int VCATCH : 1; /**< Vector fetch occurred. */
|
||||
unsigned int EXTERNAL : 1; /**< EDBGRQ signal asserted. */
|
||||
} bits; /**< Unused Bits 1. */
|
||||
} dfsr; /**< Debug Fault Status Register (0xE000ED30). */
|
||||
union
|
||||
{
|
||||
unsigned int value;
|
||||
struct
|
||||
{
|
||||
unsigned int HALTED : 1; /**< Halt requested in NVIC. */
|
||||
unsigned int BKPT : 1; /**< BKPT instruction executed. */
|
||||
unsigned int DWTTRAP : 1; /**< DWT match occurred. */
|
||||
unsigned int VCATCH : 1; /**< Vector fetch occurred. */
|
||||
unsigned int EXTERNAL : 1; /**< EDBGRQ signal asserted. */
|
||||
} bits; /**< Unused Bits 1. */
|
||||
} dfsr; /**< Debug Fault Status Register (0xE000ED30). */
|
||||
|
||||
unsigned int
|
||||
afsr; /**< Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional). */
|
||||
unsigned int afsr; /**< Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional). */
|
||||
} cb_hard_fault_regs_t;
|
||||
/** @} */
|
||||
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
;/**
|
||||
; *****************************************************************************************
|
||||
; *
|
||||
; * @file app_hardfault_kei.s
|
||||
; *
|
||||
; * @brief App HardFault Handler Function Implementation for GCC.
|
||||
; *
|
||||
; * Copyright(C) 2016-2018, Shenzhen Goodix Technology Co., Ltd
|
||||
; * All Rights Reserved
|
||||
; *
|
||||
; *****************************************************************************************
|
||||
; */
|
||||
|
||||
.syntax unified
|
||||
.thumb
|
||||
.text
|
||||
|
||||
/* NOTE: If use this file's HardFault_Handler, please comments the HardFault_Handler code on other file. */
|
||||
|
||||
.global HardFault_Handler
|
||||
.type HardFault_Handler, %function
|
||||
HardFault_Handler:
|
||||
MOV r0, lr /* get lr */
|
||||
MOV r1, sp /* get stack pointer (current is MSP) */
|
||||
BL cortex_backtrace_fault_handler
|
||||
|
||||
Fault_Loop:
|
||||
BL Fault_Loop /* while(1) */
|
||||
Executable → Regular
@@ -0,0 +1,25 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
kernel_module("app_key") {
|
||||
sources = [
|
||||
"app_key.c",
|
||||
"app_key_core.c",
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file app_key.c
|
||||
*
|
||||
* @brief App key Implementation.
|
||||
*
|
||||
*****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "app_key.h"
|
||||
#include "app_gpiote.h"
|
||||
|
||||
#ifdef ENV_USE_FREERTOS
|
||||
#include "FreeRTOS.h"
|
||||
#include "timers.h"
|
||||
#else
|
||||
#include "app_timer.h"
|
||||
#endif
|
||||
/*
|
||||
* DEFINES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#define APP_KEY_TIMER_INTERVAL 10 /**< App key polling interval interval (in units of 1ms). */
|
||||
/*
|
||||
* LOCAL VARIABLE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static uint8_t s_app_key_info[APP_KEY_REG_COUNT_MAX];
|
||||
static app_gpiote_param_t s_app_io_cfg[APP_KEY_REG_COUNT_MAX];
|
||||
static app_key_evt_cb_t s_app_key_evt_cb;
|
||||
static uint8_t s_app_key_reg_num;
|
||||
#ifdef ENV_USE_FREERTOS
|
||||
static TimerHandle_t app_key_timer_handle = NULL;
|
||||
#else
|
||||
static app_timer_id_t s_app_key_timer_id;
|
||||
#endif
|
||||
static bool s_is_timer_enabled;
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Polling app key pressed state.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static void app_key_press_state_polling(void)
|
||||
{
|
||||
app_io_pin_state_t pin_state;
|
||||
bool is_pressed = false;
|
||||
|
||||
for (uint8_t key_idx = 0; key_idx < s_app_key_reg_num; key_idx++)
|
||||
{
|
||||
is_pressed = false;
|
||||
|
||||
pin_state = app_io_read_pin(s_app_io_cfg[key_idx].type, s_app_io_cfg[key_idx].pin);
|
||||
|
||||
if (APP_IO_PIN_RESET == pin_state && s_app_io_cfg[key_idx].pull == APP_IO_PULLUP)
|
||||
{
|
||||
is_pressed = true;
|
||||
}
|
||||
else if (APP_IO_PIN_SET == pin_state && s_app_io_cfg[key_idx].pull == APP_IO_PULLDOWN)
|
||||
{
|
||||
is_pressed = true;
|
||||
}
|
||||
|
||||
app_key_core_key_pressed_record(key_idx, is_pressed);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief App key timing timeout handler.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static void app_key_timeout_handler(void *p_arg)
|
||||
{
|
||||
app_key_press_state_polling();
|
||||
app_key_core_polling_10ms();
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Start app key timer.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static void app_key_timer_start(void)
|
||||
{
|
||||
#if defined(ENV_USE_FREERTOS)
|
||||
xTimerStartFromISR(app_key_timer_handle, 0);
|
||||
#else
|
||||
app_timer_create(&s_app_key_timer_id, ATIMER_REPEAT, app_key_timeout_handler);
|
||||
app_timer_start(s_app_key_timer_id, APP_KEY_TIMER_INTERVAL, NULL);
|
||||
#endif
|
||||
s_is_timer_enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Stop app key timer.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_key_timer_stop(void)
|
||||
{
|
||||
#if defined(ENV_USE_FREERTOS)
|
||||
xTimerStopFromISR(app_key_timer_handle,0);
|
||||
#else
|
||||
app_timer_delete(&s_app_key_timer_id);
|
||||
#endif
|
||||
s_is_timer_enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief App key core event handler.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static void app_key_core_evt_handler(uint8_t key_idx, app_key_click_type_t key_click_type)
|
||||
{
|
||||
if (app_key_core_is_all_release())
|
||||
{
|
||||
app_key_timer_stop();
|
||||
}
|
||||
|
||||
s_app_key_evt_cb(s_app_key_info[key_idx], key_click_type);
|
||||
}
|
||||
|
||||
static void app_gpiote_event_handler(app_io_evt_t *p_evt)
|
||||
{
|
||||
if ( NULL == p_evt)
|
||||
return;
|
||||
|
||||
for (uint8_t key_idx = 0; key_idx < s_app_key_reg_num; key_idx++)
|
||||
{
|
||||
if ((s_app_io_cfg[key_idx].type == p_evt->type)&&
|
||||
(p_evt->pin & s_app_io_cfg[key_idx].pin))
|
||||
{
|
||||
if (!s_is_timer_enabled)
|
||||
{
|
||||
app_key_timer_start();
|
||||
}
|
||||
app_key_core_key_wait_polling_record(key_idx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
bool app_key_init(app_key_gpio_t key_inst[], uint8_t key_num, app_key_evt_cb_t key_evt_cb)
|
||||
{
|
||||
if (APP_KEY_REG_COUNT_MAX < key_num || NULL == key_evt_cb)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint8_t key_idx = 0; key_idx < key_num; key_idx++)
|
||||
{
|
||||
#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X)
|
||||
if (key_inst[key_idx].gpio_type != APP_IO_TYPE_NORMAL &&
|
||||
key_inst[key_idx].gpio_type != APP_IO_TYPE_AON)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#elif (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X)
|
||||
if (key_inst[key_idx].gpio_type != APP_IO_TYPE_GPIOA &&
|
||||
key_inst[key_idx].gpio_type != APP_IO_TYPE_GPIOB &&
|
||||
key_inst[key_idx].gpio_type != APP_IO_TYPE_GPIOC &&
|
||||
key_inst[key_idx].gpio_type != APP_IO_TYPE_AON)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
s_app_key_info[key_idx] = key_inst[key_idx].key_id;
|
||||
s_app_io_cfg[key_idx].type = key_inst[key_idx].gpio_type;
|
||||
s_app_io_cfg[key_idx].pin = key_inst[key_idx].gpio_pin;
|
||||
s_app_io_cfg[key_idx].mode = key_inst[key_idx].trigger_mode;
|
||||
s_app_io_cfg[key_idx].pull = key_inst[key_idx].pull;
|
||||
s_app_io_cfg[key_idx].io_evt_cb = app_gpiote_event_handler;
|
||||
}
|
||||
|
||||
app_gpiote_init(s_app_io_cfg, key_num);
|
||||
|
||||
s_app_key_reg_num = key_num;
|
||||
s_app_key_evt_cb = key_evt_cb;
|
||||
app_key_core_cb_register(app_key_core_evt_handler);
|
||||
|
||||
/* If using FreeRTOS, xTimer need to be create and do not create in IRQ handler */
|
||||
#if defined(ENV_USE_FREERTOS)
|
||||
#if defined(FREERTOS_V10_4_3_LTS)
|
||||
app_key_timer_handle =
|
||||
xTimerCreate(NULL, APP_KEY_TIMER_INTERVAL, pdTRUE, NULL, (TimerCallbackFunction_t)app_key_timeout_handler);
|
||||
#else
|
||||
app_key_timer_handle = xTimerCreate(NULL, APP_KEY_TIMER_INTERVAL, pdTRUE, NULL, app_key_timeout_handler);
|
||||
#endif
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file app_key.c
|
||||
*
|
||||
* @brief App Key API
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __APP_KEY_H__
|
||||
#define __APP_KEY_H__
|
||||
|
||||
#include "app_key_core.h"
|
||||
#include "app_gpiote.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @defgroup APP_KEY_STRUCT Structures
|
||||
* @{
|
||||
*/
|
||||
/**@brief App key gpio initialization variables. */
|
||||
typedef struct
|
||||
{
|
||||
app_io_type_t gpio_type; /**< Key gpio type. */
|
||||
uint32_t gpio_pin; /**< Key gpio pin. */
|
||||
app_io_mode_t trigger_mode; /**< Specifies the operating mode for the selected pin. */
|
||||
app_io_pull_t pull; /**< Pull mode.*/
|
||||
uint8_t key_id; /**< Key register ID. */
|
||||
} app_key_gpio_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup APP_KEY_TYPEDEF Typedefs
|
||||
* @{
|
||||
*/
|
||||
/**@brief APP Key event callback.*/
|
||||
typedef void (*app_key_evt_cb_t)(uint8_t key_id, app_key_click_type_t key_click_type);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup APP_KEY_FUNCTION Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief App key initialize.
|
||||
*
|
||||
* @param[in] key_inst: The array of key instance.
|
||||
* @param[in] key_num: The number of key instance.
|
||||
* @param[in] key_click_cb: App key click event callback.
|
||||
*
|
||||
* @return Result of app key inlitialization.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
bool app_key_init(app_key_gpio_t key_inst[], uint8_t key_num, app_key_evt_cb_t key_click_cb);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief App key pressed down handler.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_key_pressed_handler(app_key_gpio_t *p_app_key_info);
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,319 @@
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file app_key_core.c
|
||||
*
|
||||
* @brief App Key Core Implementation.
|
||||
*
|
||||
*****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "app_key_core.h"
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* STRUCT DEFINE
|
||||
*****************************************************************************************
|
||||
*/
|
||||
/**@brief App key core variable. */
|
||||
struct app_key_core_t
|
||||
{
|
||||
bool is_pressed;
|
||||
bool is_in_polling;
|
||||
};
|
||||
/*
|
||||
* LOCAL VARIABLE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static app_key_core_evt_cb_t s_key_core_evt_cb;
|
||||
static struct app_key_core_t s_key_core_info[APP_KEY_REG_COUNT_MAX];
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static void app_key_core_key_polling_cplt(uint8_t key_idx)
|
||||
{
|
||||
s_key_core_info[key_idx].is_pressed = false;
|
||||
s_key_core_info[key_idx].is_in_polling = false;
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief APP key click event handler.
|
||||
*
|
||||
* @param[in] key_idx: Index of key register.
|
||||
* @param[in] key_state: Key state of read procedure.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static void app_key_core_click_event_handler(uint8_t key_idx, app_key_state_t key_state)
|
||||
{
|
||||
app_key_click_type_t key_click_type = APP_KEY_NO_CLICK;
|
||||
|
||||
switch (key_state)
|
||||
{
|
||||
case APP_KEY_STA_NO_CLICK:
|
||||
key_click_type = APP_KEY_NO_CLICK;
|
||||
app_key_core_key_polling_cplt(key_idx);
|
||||
break;
|
||||
|
||||
case APP_KEY_STA_SINGLE_CLICK:
|
||||
key_click_type = APP_KEY_SINGLE_CLICK;
|
||||
app_key_core_key_polling_cplt(key_idx);
|
||||
break;
|
||||
|
||||
case APP_KEY_STA_DOUBLE_CLICK:
|
||||
key_click_type = APP_KEY_DOUBLE_CLICK;
|
||||
app_key_core_key_polling_cplt(key_idx);
|
||||
break;
|
||||
|
||||
case APP_KEY_STA_LONG_CLICK:
|
||||
key_click_type = APP_KEY_LONG_CLICK;
|
||||
break;
|
||||
|
||||
case APP_KEY_STA_CONTINUE_CLICK:
|
||||
key_click_type = APP_KEY_CONTINUE_CLICK;
|
||||
break;
|
||||
|
||||
case APP_KEY_STA_RELEASE:
|
||||
key_click_type = APP_KEY_CONTINUE_RELEASE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
s_key_core_evt_cb(key_idx, key_click_type);
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief App key state scan.
|
||||
*
|
||||
* @param[in] key_idx: Index of key.
|
||||
*
|
||||
* @return Result of scan.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static app_key_state_t app_key_core_state_scan(uint8_t key_idx)
|
||||
{
|
||||
static app_key_state_t key_scan_state[APP_KEY_REG_COUNT_MAX] = {APP_KEY_STA_INIT};
|
||||
static uint8_t key_long_click_count[APP_KEY_REG_COUNT_MAX] = {0};
|
||||
|
||||
app_key_state_t key_state_return = APP_KEY_STA_INIT;
|
||||
|
||||
switch (key_scan_state[key_idx])
|
||||
{
|
||||
case APP_KEY_STA_INIT:
|
||||
if (s_key_core_info[key_idx].is_pressed)
|
||||
{
|
||||
key_scan_state[key_idx] = APP_KEY_STA_DEBOUNCE;
|
||||
}
|
||||
break;
|
||||
|
||||
case APP_KEY_STA_DEBOUNCE:
|
||||
if (s_key_core_info[key_idx].is_pressed)
|
||||
{
|
||||
key_long_click_count[key_idx] = 0;
|
||||
key_scan_state[key_idx] = APP_KEY_STA_PRESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
key_scan_state[key_idx] = APP_KEY_STA_INIT;
|
||||
key_state_return = APP_KEY_STA_NO_CLICK;
|
||||
}
|
||||
break;
|
||||
|
||||
case APP_KEY_STA_PRESS:
|
||||
if (!s_key_core_info[key_idx].is_pressed)
|
||||
{
|
||||
key_state_return = APP_KEY_STA_SINGLE_CLICK;
|
||||
key_scan_state[key_idx] = APP_KEY_STA_INIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( APP_KEY_LONG_TIME_COUNT <= ++key_long_click_count[key_idx])
|
||||
{
|
||||
key_state_return = APP_KEY_STA_LONG_CLICK;
|
||||
key_scan_state[key_idx] = APP_KEY_STA_WAITE_RELEASE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case APP_KEY_STA_WAITE_RELEASE:
|
||||
if (!s_key_core_info[key_idx].is_pressed)
|
||||
{
|
||||
key_scan_state[key_idx] = APP_KEY_STA_INIT;
|
||||
app_key_core_key_polling_cplt(key_idx);
|
||||
key_state_return = APP_KEY_STA_RELEASE;
|
||||
}
|
||||
else
|
||||
{
|
||||
key_state_return = APP_KEY_STA_CONTINUE_CLICK;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return key_state_return;
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief App key click type read.
|
||||
*
|
||||
* @param[in] key_idx: Index of key register.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static void app_key_core_click_read(uint8_t key_idx)
|
||||
{
|
||||
static app_key_state_t key_read_state[APP_KEY_REG_COUNT_MAX] = {APP_KEY_STA_INIT};
|
||||
static uint8_t key_double_click_count[APP_KEY_REG_COUNT_MAX] = {0};
|
||||
static uint8_t key_continue_click_count[APP_KEY_REG_COUNT_MAX] = {0};
|
||||
|
||||
app_key_state_t current_key_state;
|
||||
|
||||
current_key_state = app_key_core_state_scan(key_idx);
|
||||
|
||||
switch (key_read_state[key_idx])
|
||||
{
|
||||
case APP_KEY_STA_INIT:
|
||||
if (APP_KEY_STA_SINGLE_CLICK == current_key_state)
|
||||
{
|
||||
key_double_click_count[key_idx] = 0;
|
||||
key_read_state[key_idx] = APP_KEY_STA_SINGLE_CLICK;
|
||||
}
|
||||
else if (APP_KEY_STA_NO_CLICK == current_key_state ||APP_KEY_STA_LONG_CLICK == current_key_state)
|
||||
{
|
||||
app_key_core_click_event_handler(key_idx, current_key_state);
|
||||
}
|
||||
else if (APP_KEY_STA_CONTINUE_CLICK == current_key_state)
|
||||
{
|
||||
if (APP_KEY_CONTINUE_TIME_COUNT <= ++key_continue_click_count[key_idx])
|
||||
{
|
||||
key_continue_click_count[key_idx] = 0;
|
||||
key_read_state[key_idx] = APP_KEY_STA_CONTINUE_CLICK;
|
||||
app_key_core_click_event_handler(key_idx, APP_KEY_STA_CONTINUE_CLICK);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case APP_KEY_STA_SINGLE_CLICK:
|
||||
if (APP_KEY_STA_SINGLE_CLICK == current_key_state)
|
||||
{
|
||||
key_read_state[key_idx] = APP_KEY_STA_INIT;
|
||||
app_key_core_click_event_handler(key_idx, APP_KEY_STA_DOUBLE_CLICK);
|
||||
}
|
||||
else if (APP_KEY_DOUBLE_TIME_COUNT <= ++key_double_click_count[key_idx])
|
||||
{
|
||||
key_read_state[key_idx] = APP_KEY_STA_INIT;
|
||||
app_key_core_click_event_handler(key_idx, APP_KEY_STA_SINGLE_CLICK);
|
||||
}
|
||||
break;
|
||||
|
||||
case APP_KEY_STA_CONTINUE_CLICK:
|
||||
if (APP_KEY_STA_RELEASE == current_key_state)
|
||||
{
|
||||
key_read_state[key_idx] = APP_KEY_STA_INIT;
|
||||
app_key_core_click_event_handler(key_idx, APP_KEY_STA_RELEASE);
|
||||
}
|
||||
else if (APP_KEY_STA_CONTINUE_CLICK == current_key_state)
|
||||
{
|
||||
if (APP_KEY_CONTINUE_TIME_COUNT <= ++key_continue_click_count[key_idx])
|
||||
{
|
||||
key_continue_click_count[key_idx] = 0;
|
||||
key_read_state[key_idx] = APP_KEY_STA_CONTINUE_CLICK;
|
||||
app_key_core_click_event_handler(key_idx, APP_KEY_STA_CONTINUE_CLICK);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
bool app_key_core_cb_register(app_key_core_evt_cb_t key_core_evt_cb)
|
||||
{
|
||||
if (NULL == key_core_evt_cb)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
s_key_core_evt_cb = key_core_evt_cb;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void app_key_core_polling_10ms()
|
||||
{
|
||||
for (uint8_t key_idx = 0; key_idx < APP_KEY_REG_COUNT_MAX; key_idx++)
|
||||
{
|
||||
if (s_key_core_info[key_idx].is_in_polling)
|
||||
{
|
||||
app_key_core_click_read(key_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void app_key_core_key_wait_polling_record(uint8_t key_idx)
|
||||
{
|
||||
s_key_core_info[key_idx].is_in_polling = true;
|
||||
}
|
||||
|
||||
void app_key_core_key_pressed_record(uint8_t key_idx, bool is_pressed)
|
||||
{
|
||||
s_key_core_info[key_idx].is_pressed = is_pressed;
|
||||
}
|
||||
|
||||
bool app_key_core_is_all_release(void)
|
||||
{
|
||||
for (uint8_t key_idx = 0; key_idx < APP_KEY_REG_COUNT_MAX; key_idx++)
|
||||
{
|
||||
if (s_key_core_info[key_idx].is_pressed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file App key core.h
|
||||
*
|
||||
* @brief App Key Core API
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#ifndef __APP_KEY_CORE_H__
|
||||
#define __APP_KEY_CORE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @defgroup APP_KEY_CORE_MAROC Defines
|
||||
* @{
|
||||
*/
|
||||
#define APP_KEY_REG_COUNT_MAX 10 /**< Maximum number of key instance can register, which can be configurable. */
|
||||
#define APP_KEY_DOUBLE_TIME_COUNT 50 /**< Double click time count(in unit of 10ms), which can be configurable. */
|
||||
#define APP_KEY_LONG_TIME_COUNT 100 /**< Long click time count(in uint of 10ms), which can be configurable. */
|
||||
#define APP_KEY_CONTINUE_TIME_COUNT 20 /**< Continue click time count(in uint of 10ms), which can be configurable. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup APP_KEY_CORE_ENUM Enumerations
|
||||
* @{
|
||||
*/
|
||||
/**@brief App key polling state. */
|
||||
typedef enum
|
||||
{
|
||||
APP_KEY_STA_INIT, /**< Key initialization state for key scan procedure. */
|
||||
APP_KEY_STA_DEBOUNCE, /**< Key debounce state for key scan procedure. */
|
||||
APP_KEY_STA_PRESS, /**< Key press state for key scan procedure. */
|
||||
APP_KEY_STA_WAITE_RELEASE, /**< Waite key release state for key scan procedure. */
|
||||
APP_KEY_STA_NO_CLICK, /**< Key no click state for key read procedure. */
|
||||
APP_KEY_STA_SINGLE_CLICK, /**< Key single click state for key read procedure. */
|
||||
APP_KEY_STA_DOUBLE_CLICK, /**< Key double click state for key read procedure. */
|
||||
APP_KEY_STA_LONG_CLICK, /**< Key long click state for key read procedure. */
|
||||
APP_KEY_STA_CONTINUE_CLICK, /**< Key continue click state for key read procedure. */
|
||||
APP_KEY_STA_RELEASE, /**< key continue click release state. */
|
||||
} app_key_state_t;
|
||||
|
||||
/**@brief App key click event type. */
|
||||
typedef enum
|
||||
{
|
||||
APP_KEY_NO_CLICK, /**< Key no click event. */
|
||||
APP_KEY_SINGLE_CLICK, /**< Key single click event. */
|
||||
APP_KEY_DOUBLE_CLICK, /**< Key double click event. */
|
||||
APP_KEY_LONG_CLICK, /**< Key long click event. */
|
||||
APP_KEY_CONTINUE_CLICK, /**< Key continue click event. */
|
||||
APP_KEY_CONTINUE_RELEASE /**< Key continue click release. */
|
||||
} app_key_click_type_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup APP_KEY_CORE_TYPEDEF Typedefs
|
||||
* @{
|
||||
*/
|
||||
/**@brief APP Key core event callback.*/
|
||||
typedef void (*app_key_core_evt_cb_t)(uint8_t key_idx, app_key_click_type_t key_click_type);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup APP_KEY_CORE_FUNCTION Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Register app key click event callback.
|
||||
*
|
||||
* @param[in] key_core_evt_cb: Key core event callback.
|
||||
*
|
||||
* @return Result of key core event callback is NULL or not.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
bool app_key_core_cb_register(app_key_core_evt_cb_t key_core_evt_cb);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Record app key is pressed down.
|
||||
*
|
||||
* @param[in] key_idx: Index of key register.
|
||||
* @param[in] is_pressed: True or false
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_key_core_key_pressed_record(uint8_t key_idx, bool is_pressed);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Notificaiton which key is waiting for polling.
|
||||
*
|
||||
* @param[in] key_idx: Index of key register.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_key_core_key_wait_polling_record(uint8_t key_idx);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Check all keys are released or not.
|
||||
*
|
||||
* @return Result of checking.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
bool app_key_core_is_all_release(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief App key state polling.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_key_core_polling_10ms(void);
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
kernel_module("app_linked_list") {
|
||||
sources = [ "app_linked_list.c" ]
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file app_linked_list.c
|
||||
*
|
||||
* @brief App Linked List Implementation.
|
||||
*
|
||||
*****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "app_linked_list.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t app_s_list_init(app_s_list_t *p_s_list)
|
||||
{
|
||||
if (NULL == p_s_list)
|
||||
{
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
|
||||
p_s_list->p_head = NULL;
|
||||
p_s_list->size = 0;
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
app_s_list_node_t *app_s_list_node_append(app_s_list_t *p_s_list)
|
||||
{
|
||||
app_s_list_node_t *p_iterator_node;
|
||||
app_s_list_node_t *p_s_insert_node;
|
||||
|
||||
if (NULL == p_s_list)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p_s_insert_node = app_malloc(sizeof(app_s_list_node_t));
|
||||
|
||||
if (NULL == p_s_insert_node)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(p_s_insert_node, 0, sizeof(app_s_list_node_t));
|
||||
|
||||
if (NULL == p_s_list->p_head)
|
||||
{
|
||||
p_s_list->p_head = p_s_insert_node;
|
||||
p_s_list->size = 1;
|
||||
|
||||
return p_s_insert_node;
|
||||
}
|
||||
|
||||
p_iterator_node = p_s_list->p_head;
|
||||
|
||||
while(p_iterator_node->p_next_node)
|
||||
{
|
||||
p_iterator_node = p_iterator_node->p_next_node;
|
||||
}
|
||||
|
||||
p_iterator_node->p_next_node = p_s_insert_node;
|
||||
p_s_insert_node->p_next_node = NULL;
|
||||
|
||||
p_s_list->size++;
|
||||
|
||||
return p_s_insert_node;
|
||||
}
|
||||
|
||||
app_s_list_node_t *app_s_list_node_insert(app_s_list_t *p_s_list, app_s_list_node_t *p_dgt_node, bool is_ahead)
|
||||
{
|
||||
app_s_list_node_t *p_previous_node;
|
||||
app_s_list_node_t *p_iterator_node;
|
||||
app_s_list_node_t *p_s_insert_node;
|
||||
|
||||
if (NULL == p_s_list || NULL == p_dgt_node)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p_s_insert_node = app_malloc(sizeof(app_s_list_node_t));
|
||||
|
||||
if (NULL == p_s_insert_node)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
p_previous_node = p_s_list->p_head;
|
||||
p_iterator_node = p_s_list->p_head;
|
||||
|
||||
do
|
||||
{
|
||||
if (p_iterator_node == p_dgt_node)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
p_previous_node = p_iterator_node;
|
||||
p_iterator_node = p_iterator_node->p_next_node;
|
||||
|
||||
} while (p_iterator_node);
|
||||
|
||||
if (NULL == p_iterator_node)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (is_ahead)
|
||||
{
|
||||
if (p_iterator_node == p_s_list->p_head)
|
||||
{
|
||||
p_s_insert_node->p_next_node = p_iterator_node;
|
||||
p_s_list->p_head = p_s_insert_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_s_insert_node->p_next_node = p_iterator_node;
|
||||
p_previous_node->p_next_node = p_s_insert_node;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p_s_insert_node->p_next_node = p_iterator_node->p_next_node;
|
||||
p_iterator_node->p_next_node = p_s_insert_node;
|
||||
}
|
||||
|
||||
p_s_list->size++;
|
||||
|
||||
return p_s_insert_node;
|
||||
}
|
||||
|
||||
sdk_err_t app_s_list_node_delete(app_s_list_t *p_s_list, app_s_list_node_t *p_s_list_node, bool free_data)
|
||||
{
|
||||
app_s_list_node_t *p_previous_node;
|
||||
app_s_list_node_t *p_iterator_node;
|
||||
|
||||
if (NULL == p_s_list || NULL == p_s_list_node)
|
||||
{
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
|
||||
if (p_s_list_node == p_s_list->p_head)
|
||||
{
|
||||
p_s_list->p_head = p_s_list_node->p_next_node;
|
||||
if (free_data)
|
||||
{
|
||||
app_free(p_s_list_node->p_data);
|
||||
}
|
||||
app_free(p_s_list_node);
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
p_previous_node = p_s_list->p_head;
|
||||
p_iterator_node = p_s_list->p_head;
|
||||
|
||||
do
|
||||
{
|
||||
if (p_iterator_node == p_s_list_node)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
p_previous_node = p_iterator_node;
|
||||
p_iterator_node = p_iterator_node->p_next_node;
|
||||
|
||||
} while (p_iterator_node);
|
||||
|
||||
if (NULL == p_iterator_node)
|
||||
{
|
||||
return SDK_ERR_LIST_ITEM_NOT_FOUND;
|
||||
}
|
||||
|
||||
p_previous_node->p_next_node = p_iterator_node->p_next_node;
|
||||
if (free_data)
|
||||
{
|
||||
app_free(p_s_list_node->p_data);
|
||||
}
|
||||
app_free(p_s_list_node);
|
||||
|
||||
p_s_list->size--;
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
sdk_err_t app_s_list_clear(app_s_list_t *p_s_list, bool free_data)
|
||||
{
|
||||
app_s_list_node_t *p_iterator_node;
|
||||
|
||||
if (NULL == p_s_list)
|
||||
{
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
|
||||
if (NULL == p_s_list->p_head)
|
||||
{
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
p_iterator_node = p_s_list->p_head;
|
||||
|
||||
while (p_iterator_node)
|
||||
{
|
||||
if (free_data)
|
||||
{
|
||||
app_free(p_iterator_node->p_data);
|
||||
}
|
||||
p_s_list->p_head = p_iterator_node->p_next_node;
|
||||
app_free(p_iterator_node);
|
||||
p_iterator_node = p_s_list->p_head;
|
||||
};
|
||||
|
||||
p_s_list->size = 0;
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file app_linked_list.h
|
||||
*
|
||||
* @brief App Linked List API
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __APP_LINKED_LIST_H__
|
||||
#define __APP_LINKED_LIST_H__
|
||||
|
||||
#include "grx_hal.h"
|
||||
#include "grx_sys.h"
|
||||
#include "app_memory.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @defgroup APP_LINKED_LIST_STRUCT Structures
|
||||
* @{
|
||||
*/
|
||||
/**@brief App Singly Linked List Node */
|
||||
typedef struct singly_list_node
|
||||
{
|
||||
void *p_data; /**< Pointer to data. */
|
||||
struct singly_list_node *p_next_node; /**< Pointer to next node. */
|
||||
} app_s_list_node_t;
|
||||
|
||||
/**@brief App Singly Linked List */
|
||||
typedef struct
|
||||
{
|
||||
app_s_list_node_t *p_head; /**< Pointer to head node. */
|
||||
uint32_t size; /**< Size of list. */
|
||||
} app_s_list_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup APP_LINKED_LIST_FUNCTION Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Initialize one singly linked list instance.
|
||||
*
|
||||
* @param[in] p_s_list: Pointer to a singly linked list instance.
|
||||
*
|
||||
* @return Result of initialization.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t app_s_list_init(app_s_list_t *p_s_list);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Append one singly linked list node at tail.
|
||||
*
|
||||
* @param[in] p_s_list: Pointer to a singly linked list instance.
|
||||
*
|
||||
* @return Pointer to append node.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
app_s_list_node_t *app_s_list_node_append(app_s_list_t *p_s_list);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Insert one singly linked list node into designated location.
|
||||
*
|
||||
* @param[in] p_s_list: Pointer to a singly linked list instance.
|
||||
* @param[in] p_dgt_node: Pointer to a designated singly linked list node.
|
||||
* @param[in] is_ahead: True: insert in ahead of designated node, False: insert in behind of designated node.
|
||||
*
|
||||
* @return Pointer to insert node.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
app_s_list_node_t *app_s_list_node_insert(app_s_list_t *p_s_list, app_s_list_node_t *p_dgt_node, bool is_ahead);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Delete one designated singly linked list node.
|
||||
*
|
||||
* @param[in] p_s_list: Pointer to a singly linked list instance.
|
||||
* @param[in] p_s_list_node: Pointer to a designated singly linked list node.
|
||||
* @param[in] free_data: Free node data or not.
|
||||
*
|
||||
* @return Result of delete.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t app_s_list_node_delete(app_s_list_t *p_s_list, app_s_list_node_t *p_s_list_node, bool free_data);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Clear one singly linked list instance.
|
||||
*
|
||||
* @param[in] p_s_list: Pointer to a singly linked list instance.
|
||||
* @param[in] free_data: Free node data or not.
|
||||
*
|
||||
* @return Result of clear.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t app_s_list_clear(app_s_list_t *p_s_list, bool free_data);
|
||||
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
kernel_module("app_log") {
|
||||
sources = [
|
||||
"app_log.c",
|
||||
"app_log_dump_port.c",
|
||||
"app_log_store.c",
|
||||
]
|
||||
}
|
||||
Executable → Regular
+239
-128
@@ -39,18 +39,17 @@
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "app_log.h"
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "app_log.h"
|
||||
|
||||
/*
|
||||
* DEFINE
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#if APP_LOG_COLOR_ENABLE
|
||||
/**@brief CSI(Control Sequence Introducer/Initiator) sign more information on
|
||||
* https://en.wikipedia.org/wiki/ANSI_escape_code. */
|
||||
/**@brief CSI(Control Sequence Introducer/Initiator) sign more information on https://en.wikipedia.org/wiki/ANSI_escape_code. */
|
||||
#define CSI_START "\033["
|
||||
#define CSI_END "\033[0m"
|
||||
|
||||
@@ -100,18 +99,18 @@
|
||||
|
||||
#endif
|
||||
|
||||
#define BIT_8 8
|
||||
|
||||
/*
|
||||
* STRUCTURES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
/**@brief App log environment variable. */
|
||||
struct app_log_env_t {
|
||||
struct app_log_env_t
|
||||
{
|
||||
app_log_init_t app_log_init; /**< App log initialization variables. */
|
||||
bool is_filter_set; /**< App log filter is set or not. */
|
||||
app_log_trans_func_t trans_func; /**< App log transmit function. */
|
||||
app_log_flush_func_t flush_func; /**< App log flush function. */
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -120,7 +119,8 @@ struct app_log_env_t {
|
||||
*/
|
||||
static uint8_t s_log_encode_buf[APP_LOG_LINE_BUF_SIZE]; /**< App log data encode buffer. */
|
||||
|
||||
static const char *s_log_svt_lvl_output_info[] = { /**< App log severity level outpout information. */
|
||||
static const char *s_log_svt_lvl_output_info[] = /**< App log severity level outpout information. */
|
||||
{
|
||||
[APP_LOG_LVL_ERROR] = "APP_E: ",
|
||||
[APP_LOG_LVL_WARNING] = "APP_W: ",
|
||||
[APP_LOG_LVL_INFO] = "APP_I: ",
|
||||
@@ -128,7 +128,8 @@ static const char *s_log_svt_lvl_output_info[] = { /**< App log severi
|
||||
};
|
||||
|
||||
#if APP_LOG_COLOR_ENABLE
|
||||
static const char *s_log_color_output_info[] = { /**< App log level outpout color information. */
|
||||
static const char *s_log_color_output_info[] = /**< App log level outpout color information. */
|
||||
{
|
||||
[APP_LOG_LVL_ERROR] = APP_LOG_COLOR_ERROR,
|
||||
[APP_LOG_LVL_WARNING] = APP_LOG_COLOR_WARNING,
|
||||
[APP_LOG_LVL_INFO] = APP_LOG_COLOR_INFO,
|
||||
@@ -157,17 +158,21 @@ static struct app_log_env_t s_app_log_env; /**< App log enviro
|
||||
static uint16_t app_log_strcpy(uint16_t wr_idx, uint8_t *p_log_buff, const char *p_log_data)
|
||||
{
|
||||
uint16_t cpy_length = 0;
|
||||
char *temp_p_log_data = p_log_data;
|
||||
|
||||
if (!p_log_buff || !temp_p_log_data) {
|
||||
if (!p_log_buff || !p_log_data)
|
||||
{
|
||||
return cpy_length;
|
||||
}
|
||||
|
||||
while (*temp_p_log_data != 0) {
|
||||
if ((wr_idx + cpy_length) < APP_LOG_LINE_BUF_SIZE) {
|
||||
p_log_buff[wr_idx + cpy_length] = *temp_p_log_data++;
|
||||
while (*p_log_data != 0)
|
||||
{
|
||||
if ((wr_idx + cpy_length) < APP_LOG_LINE_BUF_SIZE)
|
||||
{
|
||||
p_log_buff[wr_idx + cpy_length] = *p_log_data++;
|
||||
cpy_length++;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -187,11 +192,15 @@ static uint16_t app_log_strcpy(uint16_t wr_idx, uint8_t *p_log_buff, const char
|
||||
*/
|
||||
static bool app_log_is_fmt_set(uint8_t level, uint8_t fmt)
|
||||
{
|
||||
if (s_app_log_env.app_log_init.fmt_set[level] & fmt) {
|
||||
if (s_app_log_env.app_log_init.fmt_set[level] & fmt)
|
||||
{
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,11 +215,13 @@ static bool app_log_is_fmt_set(uint8_t level, uint8_t fmt)
|
||||
*/
|
||||
static void app_log_data_trans(uint8_t *p_data, uint16_t length)
|
||||
{
|
||||
if (p_data == NULL || length == 0) {
|
||||
if (NULL == p_data || 0 == length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_app_log_env.trans_func) {
|
||||
if (s_app_log_env.trans_func)
|
||||
{
|
||||
s_app_log_env.trans_func(p_data, length);
|
||||
}
|
||||
|
||||
@@ -225,13 +236,18 @@ static void app_log_data_trans(uint8_t *p_data, uint16_t length)
|
||||
*/
|
||||
sdk_err_t app_log_init(app_log_init_t *p_log_init, app_log_trans_func_t trans_func, app_log_flush_func_t flush_func)
|
||||
{
|
||||
if (NULL == p_log_init) {
|
||||
if (NULL == p_log_init)
|
||||
{
|
||||
s_app_log_env.is_filter_set = false;
|
||||
memset_s(&s_app_log_env.app_log_init, sizeof (s_app_log_env.app_log_init), 0, sizeof(app_log_init_t));
|
||||
} else if (p_log_init->filter.level <= APP_LOG_LVL_DEBUG) {
|
||||
memset(&s_app_log_env.app_log_init, 0, sizeof(app_log_init_t));
|
||||
}
|
||||
else if ( p_log_init->filter.level <= APP_LOG_LVL_DEBUG)
|
||||
{
|
||||
s_app_log_env.is_filter_set = true;
|
||||
memset_s(&s_app_log_env.app_log_init, sizeof (s_app_log_env.app_log_init), p_log_init, sizeof(app_log_init_t));
|
||||
} else {
|
||||
memcpy(&s_app_log_env.app_log_init, p_log_init, sizeof(app_log_init_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
return SDK_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
@@ -241,92 +257,28 @@ sdk_err_t app_log_init(app_log_init_t *p_log_init, app_log_trans_func_t trans_fu
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
uint16_t encode_name(uint8_t level, const char *file, const char *func, const long line)
|
||||
{
|
||||
uint16_t log_length = 0;
|
||||
char line_num[APP_LOG_LINE_NB_LEN_MAX + 1] = { 0 };
|
||||
|
||||
// Encode file directory name , function name and lune number info.
|
||||
if (app_log_is_fmt_set(level, APP_LOG_FMT_DIR | APP_LOG_FMT_FUNC | APP_LOG_FMT_LINE)) {
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, "(");
|
||||
|
||||
if (app_log_is_fmt_set(level, APP_LOG_FMT_DIR)) {
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, file);
|
||||
|
||||
if (app_log_is_fmt_set(level, APP_LOG_FMT_FUNC)) {
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, " ");
|
||||
} else if (app_log_is_fmt_set(level, APP_LOG_FMT_LINE)) {
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, ":");
|
||||
}
|
||||
}
|
||||
|
||||
if (app_log_is_fmt_set(level, APP_LOG_FMT_FUNC)) {
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, func);
|
||||
|
||||
if (app_log_is_fmt_set(level, APP_LOG_FMT_LINE)) {
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, " Line:");
|
||||
}
|
||||
}
|
||||
|
||||
if (app_log_is_fmt_set(level, APP_LOG_FMT_LINE)) {
|
||||
snprintf_s(line_num, sizeof (line_num), APP_LOG_LINE_NB_LEN_MAX, "%ld", line);
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, line_num);
|
||||
}
|
||||
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, ") ");
|
||||
}
|
||||
return log_length;
|
||||
}
|
||||
|
||||
uint16_t calculate_log_length(uint16_t log_length, int fmt_result)
|
||||
{
|
||||
uint8_t newline_length = strlen(APP_LOG_NEWLINE_SIGN);
|
||||
uint16_t log_len = log_length;
|
||||
// Calculate log length
|
||||
if ((fmt_result > -1) && (log_len + fmt_result) <= APP_LOG_LINE_BUF_SIZE) {
|
||||
log_len += fmt_result;
|
||||
} else {
|
||||
log_len = APP_LOG_LINE_BUF_SIZE;
|
||||
}
|
||||
|
||||
#if APP_LOG_COLOR_ENABLE
|
||||
if (log_len + (sizeof(CSI_END) - 1) + newline_length > APP_LOG_LINE_BUF_SIZE) {
|
||||
log_len = APP_LOG_LINE_BUF_SIZE;
|
||||
// Reserve some space for CSI end sign.
|
||||
log_len -= sizeof(CSI_END) - 1;
|
||||
#else
|
||||
if (log_len + newline_length > APP_LOG_LINE_BUF_SIZE) {
|
||||
log_len = APP_LOG_LINE_BUF_SIZE;
|
||||
#endif
|
||||
log_len -= newline_length;
|
||||
}
|
||||
|
||||
#if APP_LOG_COLOR_ENABLE
|
||||
// Encode CSI end sign.
|
||||
log_len += app_log_strcpy(log_len, s_log_encode_buf, CSI_END);
|
||||
#endif
|
||||
|
||||
// Encode newline sign.
|
||||
log_len += app_log_strcpy(log_len, s_log_encode_buf, APP_LOG_NEWLINE_SIGN);
|
||||
return log_len;
|
||||
}
|
||||
|
||||
void app_log_output(uint8_t level, const char *tag, const char *file, const char *func, const long line,
|
||||
const char *format, ...)
|
||||
void app_log_output(uint8_t level, const char *tag, const char *file, const char *func, const long line, const char *format, ...)
|
||||
{
|
||||
uint16_t log_length = 0;
|
||||
uint8_t newline_length = strlen(APP_LOG_NEWLINE_SIGN);
|
||||
int fmt_result = 0;
|
||||
char line_num[APP_LOG_LINE_NB_LEN_MAX + 1] = { 0 };
|
||||
va_list ap;
|
||||
|
||||
if (level > s_app_log_env.app_log_init.filter.level && s_app_log_env.is_filter_set) {
|
||||
if (level > s_app_log_env.app_log_init.filter.level && s_app_log_env.is_filter_set)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if APP_LOG_TAG_ENABLE
|
||||
if (!strstr(tag, s_app_log_env.app_log_init.filter.tag)) {
|
||||
if (!strstr(tag, s_app_log_env.app_log_init.filter.tag))
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
va_start(ap, format);
|
||||
|
||||
APP_LOG_LOCK();
|
||||
|
||||
#if APP_LOG_COLOR_ENABLE
|
||||
@@ -336,25 +288,98 @@ void app_log_output(uint8_t level, const char *tag, const char *file, const char
|
||||
#endif
|
||||
|
||||
// Encode level info.
|
||||
if (app_log_is_fmt_set(level, APP_LOG_FMT_LVL)) {
|
||||
if (app_log_is_fmt_set(level, APP_LOG_FMT_LVL))
|
||||
{
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, s_log_svt_lvl_output_info[level]);
|
||||
}
|
||||
|
||||
#if APP_LOG_TAG_ENABLE
|
||||
// Encode tag info.
|
||||
if (app_log_is_fmt_set(level, APP_LOG_FMT_TAG)) {
|
||||
if (app_log_is_fmt_set(level, APP_LOG_FMT_TAG))
|
||||
{
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, tag);
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, " ");
|
||||
}
|
||||
#endif
|
||||
log_length = encode_name(level, file, func, line);
|
||||
|
||||
// Encode file directory name , function name and lune number info.
|
||||
if (app_log_is_fmt_set(level, APP_LOG_FMT_DIR | APP_LOG_FMT_FUNC | APP_LOG_FMT_LINE))
|
||||
{
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, "(");
|
||||
|
||||
if (app_log_is_fmt_set(level, APP_LOG_FMT_DIR))
|
||||
{
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, file);
|
||||
|
||||
if (app_log_is_fmt_set(level, APP_LOG_FMT_FUNC))
|
||||
{
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, " ");
|
||||
}
|
||||
else if (app_log_is_fmt_set(level, APP_LOG_FMT_LINE))
|
||||
{
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, ":");
|
||||
}
|
||||
}
|
||||
|
||||
if (app_log_is_fmt_set(level, APP_LOG_FMT_FUNC))
|
||||
{
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, func);
|
||||
|
||||
if (app_log_is_fmt_set(level, APP_LOG_FMT_LINE))
|
||||
{
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, " Line:");
|
||||
}
|
||||
}
|
||||
|
||||
if (app_log_is_fmt_set(level, APP_LOG_FMT_LINE))
|
||||
{
|
||||
snprintf(line_num, APP_LOG_LINE_NB_LEN_MAX, "%ld", line);
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, line_num);
|
||||
}
|
||||
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, ") ");
|
||||
}
|
||||
|
||||
// Encode other log data to buffer. '\0' must be added in the end by vsnprintf. */
|
||||
fmt_result = vsnprintf_s((char *)s_log_encode_buf + log_length, sizeof (s_log_encode_buf),
|
||||
APP_LOG_LINE_BUF_SIZE - log_length, format, ap);
|
||||
fmt_result = vsnprintf((char *)s_log_encode_buf + log_length, APP_LOG_LINE_BUF_SIZE - log_length, format, ap);
|
||||
|
||||
va_end(ap);
|
||||
log_length = calculate_log_length(log_length, fmt_result);
|
||||
|
||||
// Calculate log length
|
||||
if ((fmt_result > -1) && (log_length + fmt_result) <= APP_LOG_LINE_BUF_SIZE)
|
||||
{
|
||||
log_length += fmt_result;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_length = APP_LOG_LINE_BUF_SIZE;
|
||||
}
|
||||
|
||||
#if APP_LOG_COLOR_ENABLE
|
||||
if (log_length + (sizeof(CSI_END) - 1) + newline_length > APP_LOG_LINE_BUF_SIZE)
|
||||
{
|
||||
log_length = APP_LOG_LINE_BUF_SIZE;
|
||||
// Reserve some space for CSI end sign.
|
||||
log_length -= sizeof(CSI_END) - 1;
|
||||
#else
|
||||
if (log_length + newline_length > APP_LOG_LINE_BUF_SIZE)
|
||||
{
|
||||
log_length = APP_LOG_LINE_BUF_SIZE;
|
||||
#endif
|
||||
log_length -= newline_length;
|
||||
}
|
||||
|
||||
#if APP_LOG_COLOR_ENABLE
|
||||
// Encode CSI end sign.
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, CSI_END);
|
||||
#endif
|
||||
|
||||
// Encode newline sign.
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, APP_LOG_NEWLINE_SIGN);
|
||||
|
||||
|
||||
app_log_data_trans(s_log_encode_buf, log_length);
|
||||
|
||||
APP_LOG_UNLOCK();
|
||||
}
|
||||
|
||||
@@ -368,10 +393,14 @@ void app_log_raw_info(const char *format, ...)
|
||||
|
||||
APP_LOG_LOCK();
|
||||
|
||||
fmt_result = vsnprintf_s((char *)s_log_encode_buf, sizeof(s_log_encode_buf), APP_LOG_LINE_BUF_SIZE, format, ap);
|
||||
if ((fmt_result > -1) && (fmt_result) <= APP_LOG_LINE_BUF_SIZE) {
|
||||
fmt_result = vsnprintf((char *)s_log_encode_buf, APP_LOG_LINE_BUF_SIZE, format, ap);
|
||||
|
||||
if ((fmt_result > -1) && (fmt_result) <= APP_LOG_LINE_BUF_SIZE)
|
||||
{
|
||||
log_length = fmt_result;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_length = APP_LOG_LINE_BUF_SIZE;
|
||||
}
|
||||
|
||||
@@ -380,50 +409,132 @@ void app_log_raw_info(const char *format, ...)
|
||||
APP_LOG_UNLOCK();
|
||||
}
|
||||
|
||||
void app_log_hex_dump(uint8_t *p_data, uint16_t length)
|
||||
void app_log_hex_dump(void *p_data, uint16_t length)
|
||||
{
|
||||
uint16_t log_length = 0;
|
||||
uint16_t convert_idx = 0;
|
||||
uint16_t line_num = 0;
|
||||
char dump_str[8] = {0};
|
||||
|
||||
APP_LOG_LOCK();
|
||||
|
||||
for (convert_idx = 0; convert_idx < length; convert_idx++) {
|
||||
if (log_length >= APP_LOG_LINE_BUF_SIZE) {
|
||||
log_length = APP_LOG_LINE_BUF_SIZE;
|
||||
break;
|
||||
line_num = length / APP_LOG_PER_LINE_HEX_DUMP_SIZE;
|
||||
|
||||
for (uint8_t i = 0; i < line_num; i ++)
|
||||
{
|
||||
if (app_log_is_fmt_set(APP_LOG_LVL_DEBUG, APP_LOG_FMT_LVL))
|
||||
{
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, s_log_svt_lvl_output_info[APP_LOG_LVL_DEBUG]);
|
||||
}
|
||||
|
||||
if (p_data[convert_idx] < ' ') {
|
||||
s_log_encode_buf[log_length] = '.';
|
||||
log_length++;
|
||||
} else {
|
||||
snprintf_s(dump_str, sizeof (dump_str), BIT_8, "%02X ", p_data[convert_idx]);
|
||||
for (uint8_t j = 0; j < APP_LOG_PER_LINE_HEX_DUMP_SIZE; j++)
|
||||
{
|
||||
snprintf(dump_str, 8, "%02X ", ((uint8_t *)p_data)[convert_idx++]);
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, dump_str);
|
||||
}
|
||||
|
||||
if (convert_idx % APP_LOG_PER_LINE_HEX_DUMP_SIZE == 0)
|
||||
{
|
||||
snprintf(dump_str, 8, " | ");
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, dump_str);
|
||||
convert_idx -= APP_LOG_PER_LINE_HEX_DUMP_SIZE;
|
||||
for (uint8_t j = 0; j < APP_LOG_PER_LINE_HEX_DUMP_SIZE; j++)
|
||||
{
|
||||
if (((uint8_t *)p_data)[convert_idx] < ' ' || ((uint8_t *)p_data)[convert_idx] > 0x7f)
|
||||
{
|
||||
s_log_encode_buf[log_length] = '.';
|
||||
log_length++;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_log_encode_buf[log_length] = ((uint8_t *)p_data)[convert_idx];
|
||||
log_length++;
|
||||
}
|
||||
convert_idx++;
|
||||
}
|
||||
}
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, APP_LOG_NEWLINE_SIGN);
|
||||
app_log_data_trans(s_log_encode_buf, log_length);
|
||||
log_length = 0;
|
||||
}
|
||||
|
||||
app_log_data_trans(s_log_encode_buf, log_length);
|
||||
if (length % APP_LOG_PER_LINE_HEX_DUMP_SIZE)
|
||||
{
|
||||
if (app_log_is_fmt_set(APP_LOG_LVL_DEBUG, APP_LOG_FMT_LVL))
|
||||
{
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, s_log_svt_lvl_output_info[APP_LOG_LVL_DEBUG]);
|
||||
}
|
||||
|
||||
for (uint8_t j = 0; j < length % APP_LOG_PER_LINE_HEX_DUMP_SIZE; j++)
|
||||
{
|
||||
snprintf(dump_str, 8, "%02X ", ((uint8_t *)p_data)[convert_idx++]);
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, dump_str);
|
||||
}
|
||||
|
||||
for (uint8_t j = 0; j < APP_LOG_PER_LINE_HEX_DUMP_SIZE -length % APP_LOG_PER_LINE_HEX_DUMP_SIZE; j++)
|
||||
{
|
||||
snprintf(dump_str, 8, " ");
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, dump_str);
|
||||
}
|
||||
|
||||
snprintf(dump_str, 8, " | ");
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, dump_str);
|
||||
convert_idx -= length % APP_LOG_PER_LINE_HEX_DUMP_SIZE;
|
||||
for (uint8_t j = 0; j < length % APP_LOG_PER_LINE_HEX_DUMP_SIZE; j++)
|
||||
{
|
||||
if (((uint8_t *)p_data)[convert_idx] < ' ' || ((uint8_t *)p_data)[convert_idx] > 0x7f)
|
||||
{
|
||||
s_log_encode_buf[log_length] = '.';
|
||||
log_length++;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_log_encode_buf[log_length] = ((uint8_t *)p_data)[convert_idx];
|
||||
log_length++;
|
||||
}
|
||||
convert_idx++;
|
||||
}
|
||||
|
||||
log_length += app_log_strcpy(log_length, s_log_encode_buf, APP_LOG_NEWLINE_SIGN);
|
||||
app_log_data_trans(s_log_encode_buf, log_length);
|
||||
}
|
||||
|
||||
APP_LOG_UNLOCK();
|
||||
}
|
||||
|
||||
void app_log_flush(void)
|
||||
{
|
||||
if (s_app_log_env.flush_func) {
|
||||
if (s_app_log_env.flush_func)
|
||||
{
|
||||
s_app_log_env.flush_func();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if IO_REDIRECT == 0
|
||||
#if defined(__CC_ARM)
|
||||
|
||||
struct __FILE {
|
||||
struct __FILE
|
||||
{
|
||||
int handle;
|
||||
};
|
||||
|
||||
FILE s_stdout;
|
||||
FILE s_stdin;
|
||||
FILE __stdout;
|
||||
FILE __stdin;
|
||||
|
||||
#if !defined(__MICROLIB)
|
||||
void _sys_exit(int x) {
|
||||
x = x;
|
||||
}
|
||||
|
||||
void _ttywrch(int ch) {
|
||||
ch = ch;
|
||||
}
|
||||
|
||||
void _sys_command_string(int y) {
|
||||
y = y;
|
||||
}
|
||||
#endif
|
||||
|
||||
int fputc(int ch, FILE *file)
|
||||
{
|
||||
@@ -437,11 +548,11 @@ int fputc(int ch, FILE *file)
|
||||
int _write(int file, const char *buf, int len)
|
||||
{
|
||||
int tx_len = 0;
|
||||
char *temp_buf = buf;
|
||||
|
||||
while (tx_len < len) {
|
||||
while (tx_len < len)
|
||||
{
|
||||
app_log_data_trans((uint8_t *)buf, 1);
|
||||
temp_buf++;
|
||||
buf++;
|
||||
tx_len++;
|
||||
}
|
||||
return tx_len;
|
||||
@@ -449,14 +560,14 @@ int _write(int file, const char *buf, int len)
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
|
||||
size_t s_write(int handle, const unsigned char *buf, size_t size)
|
||||
size_t __write(int handle, const unsigned char *buf, size_t size)
|
||||
{
|
||||
size_t len = 0;
|
||||
unsigned char* temp_buf = buf;
|
||||
|
||||
while (len < size) {
|
||||
while (len < size)
|
||||
{
|
||||
app_log_data_trans((uint8_t *)buf, 1);
|
||||
temp_buf++;
|
||||
buf++;
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
|
||||
Executable → Regular
+43
-42
@@ -39,8 +39,8 @@
|
||||
#define __APP_LOG_H__
|
||||
|
||||
#include "custom_config.h"
|
||||
#include "gr55xx_sys.h"
|
||||
#include "gr55xx_hal.h"
|
||||
#include "grx_sys.h"
|
||||
#include "grx_hal.h"
|
||||
#if APP_LOG_STORE_ENABLE
|
||||
#include "app_log_store.h"
|
||||
#endif
|
||||
@@ -71,11 +71,12 @@
|
||||
#define APP_LOG_UNLOCK() LOCAL_INT_RESTORE() /**< APP log unlock. */
|
||||
|
||||
#ifndef APP_LOG_TAG
|
||||
#define APP_LOG_TAG "NO_TAG" /**< Default app log tag. */
|
||||
#define APP_LOG_TAG "NO_TAG" /**< Default app log tag. */
|
||||
#endif
|
||||
|
||||
#define APP_LOG_LINE_BUF_SIZE 256 /**< Buffer size for every line's log. */
|
||||
#define APP_LOG_SEVERITY_LEVEL APP_LOG_LVL_DEBUG /**< Default log severity level. */
|
||||
#define APP_LOG_PER_LINE_HEX_DUMP_SIZE 8 /**< Hex char dump size in per line. */
|
||||
#define APP_LOG_SEVERITY_LEVEL APP_LOG_LVL_DEBUG /**< Default log severity level. */
|
||||
#define APP_LOG_TAG_LEN_MAX 20 /**< Maximum length of output filter's tag. */
|
||||
#define APP_LOG_LINE_NB_LEN_MAX 5 /**< Maximum length of output line number. */
|
||||
#define APP_LOG_NEWLINE_SIGN "\r\n" /**< Newline sign output. */
|
||||
@@ -106,43 +107,39 @@
|
||||
/** @} */
|
||||
|
||||
#if APP_LOG_PRINTF_ENABLE
|
||||
#if APP_LOG_SEVERITY_LEVEL >= APP_LOG_LVL_ERROR
|
||||
#define APP_LOG_ERROR(...) app_log_output(APP_LOG_LVL_ERROR, APP_LOG_TAG, \
|
||||
__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define APP_LOG_ERROR(...)
|
||||
#endif
|
||||
#if APP_LOG_SEVERITY_LEVEL >= APP_LOG_LVL_ERROR
|
||||
#define APP_LOG_ERROR(...) app_log_output(APP_LOG_LVL_ERROR, APP_LOG_TAG, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define APP_LOG_ERROR(...)
|
||||
#endif
|
||||
|
||||
#if APP_LOG_SEVERITY_LEVEL >= APP_LOG_LVL_WARNING
|
||||
#define APP_LOG_WARNING(...) app_log_output(APP_LOG_LVL_WARNING, APP_LOG_TAG, __FILE__, \
|
||||
__FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define APP_LOG_WARNING(...)
|
||||
#endif
|
||||
#if APP_LOG_SEVERITY_LEVEL >= APP_LOG_LVL_WARNING
|
||||
#define APP_LOG_WARNING(...) app_log_output(APP_LOG_LVL_WARNING, APP_LOG_TAG, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define APP_LOG_WARNING(...)
|
||||
#endif
|
||||
|
||||
#if APP_LOG_SEVERITY_LEVEL >= APP_LOG_LVL_INFO
|
||||
#define APP_LOG_INFO(...) app_log_output(APP_LOG_LVL_INFO, APP_LOG_TAG, __FILE__, \
|
||||
__FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define APP_LOG_INFO(...)
|
||||
#endif
|
||||
#if APP_LOG_SEVERITY_LEVEL >= APP_LOG_LVL_INFO
|
||||
#define APP_LOG_INFO(...) app_log_output(APP_LOG_LVL_INFO, APP_LOG_TAG, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define APP_LOG_INFO(...)
|
||||
#endif
|
||||
|
||||
#if APP_LOG_SEVERITY_LEVEL >= APP_LOG_LVL_DEBUG
|
||||
#define APP_LOG_DEBUG(...) app_log_output(APP_LOG_LVL_DEBUG, APP_LOG_TAG, __FILE__, \
|
||||
__FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define APP_LOG_DEBUG(...)
|
||||
#endif
|
||||
#if APP_LOG_SEVERITY_LEVEL >= APP_LOG_LVL_DEBUG
|
||||
#define APP_LOG_DEBUG(...) app_log_output(APP_LOG_LVL_DEBUG, APP_LOG_TAG, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define APP_LOG_DEBUG(...)
|
||||
#endif
|
||||
|
||||
#define APP_LOG_RAW_INFO(...) app_log_raw_info(__VA_ARGS__)
|
||||
#define APP_LOG_HEX_DUMP(p_data, length) app_log_hex_dump(p_data, length)
|
||||
#define APP_LOG_RAW_INFO(...) app_log_raw_info( __VA_ARGS__)
|
||||
#define APP_LOG_HEX_DUMP(p_data, length) app_log_hex_dump(p_data, length)
|
||||
#else
|
||||
#define APP_LOG_ERROR(...)
|
||||
#define APP_LOG_WARNING(...)
|
||||
#define APP_LOG_INFO(...)
|
||||
#define APP_LOG_DEBUG(...)
|
||||
#define APP_LOG_RAW_INFO(...)
|
||||
#define APP_LOG_HEX_DUMP(p_data, length)
|
||||
#define APP_LOG_ERROR(...)
|
||||
#define APP_LOG_WARNING(...)
|
||||
#define APP_LOG_INFO(...)
|
||||
#define APP_LOG_DEBUG(...)
|
||||
#define APP_LOG_RAW_INFO(...)
|
||||
#define APP_LOG_HEX_DUMP(p_data, length)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
@@ -162,13 +159,15 @@ typedef void (*app_log_flush_func_t)(void);
|
||||
* @{
|
||||
*/
|
||||
/**@brief App log filter. */
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
uint8_t level; /**< App log filter level. */
|
||||
char tag[APP_LOG_TAG_LEN_MAX + 1]; /**< App log filter tag. */
|
||||
} app_log_filter_t;
|
||||
|
||||
/**@brief App log init stucture. */
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
app_log_filter_t filter; /**< App log filter. */
|
||||
uint8_t fmt_set[APP_LOG_LVL_NB]; /**< Format of app log. See @ref APP_LOG_FMT.*/
|
||||
} app_log_init_t;
|
||||
@@ -185,7 +184,6 @@ typedef struct {
|
||||
* @param[in] p_log_feat: Pointer to app log feature set.
|
||||
* @param[in] trans_func: App log transmit function.
|
||||
* @param[in] flush_func: App log flush function.
|
||||
|
||||
*
|
||||
* @return Result of initialization.
|
||||
*****************************************************************************************
|
||||
@@ -205,8 +203,7 @@ sdk_err_t app_log_init(app_log_init_t *p_log_init, app_log_trans_func_t trans_fu
|
||||
* @param[in] ...: Arguments.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_log_output(uint8_t level, const char *tag, const char *file, const char *func, const long line,
|
||||
const char *format, ...);
|
||||
void app_log_output(uint8_t level, const char *tag, const char *file, const char *func, const long line, const char *format, ...);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
@@ -226,7 +223,7 @@ void app_log_raw_info(const char *format, ...);
|
||||
* @param[in] length Length of data.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_log_hex_dump(uint8_t *p_data, uint16_t length);
|
||||
void app_log_hex_dump(void *p_data, uint16_t length);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
@@ -237,3 +234,7 @@ void app_log_flush(void);
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file app_log_store_dump_port.c
|
||||
*
|
||||
* @brief App Log store dump port Implementation.
|
||||
*
|
||||
*****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
#include "app_log_dump_port.h"
|
||||
#include "app_log_store.h"
|
||||
#include "lms.h"
|
||||
#include "app_error.h"
|
||||
#include "custom_config.h"
|
||||
|
||||
#if APP_LOG_STORE_ENABLE
|
||||
/*
|
||||
* DEFINE
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* STRUCTURES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCAL VARIABLE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static void lms_log_length_send(uint32_t log_len);
|
||||
static void lms_data_send(uint8_t *p_data, uint16_t length);
|
||||
static void lms_data_send_finish_cb(void);
|
||||
static app_log_dump_cbs_t s_dump_cbs =
|
||||
{
|
||||
.dump_start_cb = lms_log_length_send,
|
||||
.dump_process_cb = lms_data_send,
|
||||
.dump_finish_cb = lms_data_send_finish_cb
|
||||
};
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static uint8_t *s_send_data_addr = NULL;
|
||||
static uint16_t s_send_block_size = 0;
|
||||
static uint32_t s_sended_len = 0;
|
||||
static uint16_t s_once_size = 20;
|
||||
static uint32_t s_checksum = 0;
|
||||
|
||||
static void lms_log_length_send(uint32_t log_len)
|
||||
{
|
||||
sdk_err_t error_code;
|
||||
uint8_t arr[10] = {0};
|
||||
arr[0] = 0x81;
|
||||
arr[1] = 0;
|
||||
arr[2] = log_len;
|
||||
arr[3] = log_len >> 8;
|
||||
arr[4] = log_len >> 16;
|
||||
arr[5] = log_len >> 24;
|
||||
error_code = lms_notify_cmd(0, arr, 6);
|
||||
APP_ERROR_CHECK(error_code);
|
||||
}
|
||||
|
||||
static void lms_data_send(uint8_t *p_data, uint16_t length)
|
||||
{
|
||||
for(uint16_t i = 0; i < length; i++)
|
||||
s_checksum += p_data[i];
|
||||
|
||||
sdk_err_t error_code;
|
||||
s_send_block_size = length;
|
||||
s_send_data_addr = p_data;
|
||||
|
||||
if (s_send_block_size > s_once_size)
|
||||
{
|
||||
s_sended_len += s_once_size;
|
||||
error_code = lms_notify_data(0, s_send_data_addr, s_once_size);
|
||||
APP_ERROR_CHECK(error_code);
|
||||
}
|
||||
else
|
||||
{
|
||||
s_sended_len += s_send_block_size;
|
||||
error_code = lms_notify_data(0, s_send_data_addr, s_send_block_size);
|
||||
APP_ERROR_CHECK(error_code);
|
||||
}
|
||||
}
|
||||
static void lms_data_continue_send(void)
|
||||
{
|
||||
if (NULL == s_send_data_addr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
sdk_err_t error_code;
|
||||
uint16_t remain = s_send_block_size - s_sended_len;
|
||||
uint16_t offset = 0;
|
||||
|
||||
if (remain > s_once_size)
|
||||
{
|
||||
offset = s_sended_len;
|
||||
s_sended_len += s_once_size;
|
||||
|
||||
error_code = lms_notify_data(0, &s_send_data_addr[offset], s_once_size);
|
||||
APP_ERROR_CHECK(error_code);
|
||||
}
|
||||
else if(remain > 0)
|
||||
{
|
||||
offset = s_sended_len;
|
||||
s_sended_len += remain;
|
||||
error_code = lms_notify_data(0, &s_send_data_addr[offset],remain);
|
||||
APP_ERROR_CHECK(error_code);
|
||||
}
|
||||
else
|
||||
{
|
||||
//vPortFree(s_send_data_addr);
|
||||
s_send_data_addr = NULL;
|
||||
s_send_block_size = 0;
|
||||
s_sended_len = 0;
|
||||
app_log_dump_continue();
|
||||
}
|
||||
}
|
||||
|
||||
static void lms_data_send_finish_cb(void)
|
||||
{
|
||||
uint8_t arr[5] = {0};
|
||||
arr[0] = 0xc1;
|
||||
arr[1] = s_checksum;
|
||||
arr[2] = s_checksum >> 8;
|
||||
arr[3] = s_checksum >> 16;
|
||||
arr[4] = s_checksum >> 24;
|
||||
lms_notify_cmd(0, arr, 5);
|
||||
s_checksum = 0;
|
||||
}
|
||||
|
||||
static void lms_service_process_event(lms_evt_t *p_evt)
|
||||
{
|
||||
uint8_t arr[10] = {0};
|
||||
sdk_err_t error_code;
|
||||
switch (p_evt->evt_type)
|
||||
{
|
||||
case LMS_EVT_CMD_RECEIVE_DATA:
|
||||
if (1 == p_evt->p_data[0])
|
||||
{
|
||||
error_code = app_log_store_dump(&s_dump_cbs);
|
||||
if (error_code)
|
||||
{
|
||||
arr[0] = 0x81;
|
||||
arr[1] = error_code;
|
||||
error_code = lms_notify_cmd(0, arr, 6);
|
||||
APP_ERROR_CHECK(error_code);
|
||||
}
|
||||
}
|
||||
else if(2 == p_evt->p_data[0])
|
||||
{
|
||||
error_code = app_log_store_clear();
|
||||
APP_ERROR_CHECK(error_code);
|
||||
arr[0] = 0x82;
|
||||
arr[1] = 0;
|
||||
error_code = lms_notify_cmd(0, arr, 2);
|
||||
APP_ERROR_CHECK(error_code);
|
||||
}
|
||||
break;
|
||||
|
||||
case LMS_EVT_CMD_NOTIFY_COMPLETE:
|
||||
break;
|
||||
|
||||
case LMS_EVT_DATA_RECEIVE_DATA:
|
||||
break;
|
||||
|
||||
case LMS_EVT_DATA_NOTIFY_COMPLETE:
|
||||
lms_data_continue_send();
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void lms_update_mtu_size(uint16_t new_mtu)
|
||||
{
|
||||
s_once_size = new_mtu - 3;
|
||||
}
|
||||
|
||||
void app_log_dump_service_init(void)
|
||||
{
|
||||
sdk_err_t error_code;
|
||||
lms_init_t lms_init;
|
||||
|
||||
lms_init.evt_handler = lms_service_process_event;
|
||||
|
||||
error_code = lms_service_init(&lms_init);
|
||||
APP_ERROR_CHECK(error_code);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file app_log_dump_port.h
|
||||
*
|
||||
* @brief App Log dump port API
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __APP_LOG_DUMP_PORTH__
|
||||
#define __APP_LOG_DUMP_PORTH__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Update the Length of log data packet.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void lms_update_mtu_size(uint16_t new_mtu);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Init log dump service.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_log_dump_service_init(void);
|
||||
#endif
|
||||
|
||||
|
||||
Executable → Regular
+231
-152
@@ -40,6 +40,7 @@
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "app_log_store.h"
|
||||
#if APP_LOG_STORE_ENABLE
|
||||
#include "utility.h"
|
||||
|
||||
@@ -52,21 +53,19 @@
|
||||
#define APP_LOG_STORE_TIME_DEFAULT "[1970/01/01 00:00:00:000] "
|
||||
#define APP_LOG_STORE_CACHE_SIZE ((APP_LOG_STORE_LINE_SIZE) * (APP_LOG_STORE_CACHE_NUM))
|
||||
#define APP_LOG_STORE_ONECE_OP_SIZE 1024
|
||||
#define APP_LOG_STORE_BUSY_BIT (0x01 << 0)
|
||||
#define APP_LOG_STORE_CLEAR_BIT (0x01 << 0)
|
||||
#define APP_LOG_STORE_SAVE_BIT (0x01 << 1)
|
||||
#define APP_LOG_STORE_DUMP_BIT (0x01 << 2)
|
||||
|
||||
#define OFFSET_0 0
|
||||
#define OFFSET_1 1
|
||||
#define OFFSET_2 2
|
||||
|
||||
#define APP_LOG_STORE_DUMP_READY_BIT (0x01 << 3)
|
||||
#define APP_LOG_STORE_DUMP_START_BIT (0x01 << 4)
|
||||
|
||||
/*
|
||||
* STRUCTURES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
/**@brief App log store head info. */
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
uint32_t magic; /**< Magic for app log store. */
|
||||
uint32_t db_addr; /**< Start address of app log db flash. */
|
||||
uint32_t db_size; /**< Size of app log db flash. */
|
||||
@@ -76,7 +75,8 @@ typedef struct {
|
||||
} log_store_head_t;
|
||||
|
||||
/**@brief App log store environment variable. */
|
||||
struct log_store_env_t {
|
||||
struct log_store_env_t
|
||||
{
|
||||
bool initialized;
|
||||
uint8_t store_status;
|
||||
log_store_head_t store_head;
|
||||
@@ -90,10 +90,11 @@ struct log_store_env_t {
|
||||
*/
|
||||
static struct log_store_env_t s_log_store_env;
|
||||
static app_log_store_op_t s_log_store_ops;
|
||||
static app_log_store_dump_cb_t s_log_store_dump_cb;
|
||||
static app_log_dump_cbs_t *s_log_dump_cbs;
|
||||
static uint32_t s_log_store_dump_offset;
|
||||
static ring_buffer_t s_log_store_rbuf;
|
||||
static uint8_t s_log_store_cache[APP_LOG_STORE_CACHE_SIZE];
|
||||
static ring_buffer_t s_log_store_rbuf __attribute__((section("RAM_CODE"))) = {0};
|
||||
static uint8_t s_log_store_cache[APP_LOG_STORE_CACHE_SIZE] __attribute__((section("RAM_CODE"))) = {0};
|
||||
static uint8_t s_read_dump_buffer[APP_LOG_STORE_ONECE_OP_SIZE];
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DEFINITIONS
|
||||
@@ -103,8 +104,10 @@ static uint32_t log_store_check_sum_calc(uint8_t *p_data, uint32_t len)
|
||||
{
|
||||
uint32_t check_sum = 0;
|
||||
|
||||
if (p_data && len) {
|
||||
for (uint8_t i = 0; i < len; i++) {
|
||||
if (p_data && len)
|
||||
{
|
||||
for (uint8_t i = 0; i < len; i++)
|
||||
{
|
||||
check_sum += p_data[i];
|
||||
}
|
||||
}
|
||||
@@ -118,13 +121,15 @@ static bool log_store_head_check(log_store_head_t *p_head, uint32_t db_addr, uin
|
||||
uint8_t *head_data = (uint8_t *)p_head;
|
||||
|
||||
if (p_head->magic != APP_LOG_STORE_MAGIC ||
|
||||
p_head->db_addr != db_addr ||
|
||||
p_head->db_size != db_size ||
|
||||
p_head->offset > db_size) {
|
||||
p_head->db_addr != db_addr ||
|
||||
p_head->db_size != db_size ||
|
||||
p_head->offset > db_size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p_head->check_sum != log_store_check_sum_calc(head_data, head_len - OFFSET_2)) {
|
||||
if (p_head->check_sum != log_store_check_sum_calc(head_data, head_len - 2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -136,9 +141,10 @@ static bool log_store_head_update(uint16_t nv_tag, log_store_head_t *p_head)
|
||||
uint16_t head_len = sizeof(log_store_head_t);
|
||||
uint8_t *head_data = (uint8_t *)p_head;
|
||||
|
||||
p_head->check_sum = log_store_check_sum_calc(head_data, head_len - OFFSET_2);
|
||||
p_head->check_sum = log_store_check_sum_calc(head_data, head_len - 2);
|
||||
|
||||
if (nvds_put(nv_tag, head_len, (uint8_t *)p_head)) {
|
||||
if (nvds_put(nv_tag, head_len, (uint8_t *)p_head))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -147,7 +153,8 @@ static bool log_store_head_update(uint16_t nv_tag, log_store_head_t *p_head)
|
||||
|
||||
static bool log_store_time_stamp_encode(uint8_t *p_buffer, uint8_t buffer_size)
|
||||
{
|
||||
if (buffer_size != APP_LOG_STORE_TIME_SIZE) {
|
||||
if (APP_LOG_STORE_TIME_SIZE != buffer_size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -155,12 +162,12 @@ static bool log_store_time_stamp_encode(uint8_t *p_buffer, uint8_t buffer_size)
|
||||
|
||||
s_log_store_ops.time_get(&rtc_time);
|
||||
|
||||
if (APP_LOG_STORE_TIME_SIZE == snprintf_s((char *)p_buffer, APP_LOG_STORE_TIME_SIZE, \
|
||||
APP_LOG_STORE_TIME_SIZE, \
|
||||
"[%04d/%02d/%02d %02d:%02d:%02d:%03d] ", \
|
||||
rtc_time.year, rtc_time.month, rtc_time.day, \
|
||||
rtc_time.hour, rtc_time.min, \
|
||||
rtc_time.sec, rtc_time.msec)) {
|
||||
if (APP_LOG_STORE_TIME_SIZE == snprintf((char *)p_buffer,
|
||||
APP_LOG_STORE_TIME_SIZE,
|
||||
"[%04d/%02d/%02d %02d:%02d:%02d:%03d] ",
|
||||
rtc_time.year, rtc_time.month, rtc_time.day,
|
||||
rtc_time.hour, rtc_time.min, rtc_time.sec, rtc_time.msec))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -171,97 +178,141 @@ static void log_store_data_flash_write(void)
|
||||
{
|
||||
uint32_t align_num = 0;
|
||||
uint32_t read_len;
|
||||
uint8_t read_buff[APP_LOG_STORE_ONECE_OP_SIZE];
|
||||
uint8_t *read_buff = s_read_dump_buffer;
|
||||
|
||||
if ((s_log_store_env.store_head.offset % s_log_store_env.blk_size) == 0) {
|
||||
if (s_log_store_ops.flash_erase) {
|
||||
if (0 == (s_log_store_env.store_head.offset % s_log_store_env.blk_size))
|
||||
{
|
||||
if (s_log_store_ops.flash_erase)
|
||||
{
|
||||
s_log_store_ops.flash_erase(s_log_store_env.store_head.db_addr + s_log_store_env.store_head.offset,
|
||||
s_log_store_env.blk_size);
|
||||
}
|
||||
}
|
||||
|
||||
align_num = ALIGN_NUM(APP_LOG_STORE_ONECE_OP_SIZE, s_log_store_env.store_head.offset);
|
||||
if (align_num != s_log_store_env.store_head.offset) {
|
||||
|
||||
if (align_num != s_log_store_env.store_head.offset)
|
||||
{
|
||||
read_len = ring_buffer_read(&s_log_store_rbuf, read_buff, align_num - s_log_store_env.store_head.offset);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
read_len = ring_buffer_read(&s_log_store_rbuf, read_buff, APP_LOG_STORE_ONECE_OP_SIZE);
|
||||
}
|
||||
|
||||
if (s_log_store_ops.flash_write && read_len) {
|
||||
s_log_store_ops.flash_write(s_log_store_env.store_head.db_addr + s_log_store_env.store_head.offset, read_buff,
|
||||
read_len);
|
||||
if (s_log_store_ops.flash_write && read_len)
|
||||
{
|
||||
s_log_store_ops.flash_write(s_log_store_env.store_head.db_addr + s_log_store_env.store_head.offset, read_buff, read_len);
|
||||
s_log_store_env.store_head.offset += read_len;
|
||||
}
|
||||
|
||||
if (s_log_store_env.store_head.offset >= s_log_store_env.store_head.db_size) {
|
||||
if (s_log_store_env.store_head.offset >= s_log_store_env.store_head.db_size)
|
||||
{
|
||||
s_log_store_env.store_head.offset = 0;
|
||||
s_log_store_env.store_head.flip_over = 1;
|
||||
}
|
||||
|
||||
log_store_head_update(s_log_store_env.head_nv_tag, &s_log_store_env.store_head);
|
||||
|
||||
}
|
||||
|
||||
static void log_store_to_flash(void)
|
||||
{
|
||||
#if (APP_LOG_STORE_RUN_ON_OS == 0)
|
||||
if (s_log_store_env.store_status & APP_LOG_STORE_BUSY_BIT) {
|
||||
return;
|
||||
}
|
||||
|
||||
s_log_store_env.store_status |= APP_LOG_STORE_BUSY_BIT;
|
||||
#endif
|
||||
|
||||
log_store_data_flash_write();
|
||||
|
||||
s_log_store_env.store_status &= ~APP_LOG_STORE_SAVE_BIT;
|
||||
#if (APP_LOG_STORE_RUN_ON_OS == 0)
|
||||
s_log_store_env.store_status &= ~APP_LOG_STORE_BUSY_BIT;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void log_dump_from_flash(void)
|
||||
{
|
||||
uint8_t dump_buffer[APP_LOG_STORE_ONECE_OP_SIZE];
|
||||
uint8_t *dump_buffer = s_read_dump_buffer;
|
||||
uint16_t dump_len;
|
||||
uint32_t need_dump_size = s_log_store_env.store_head.flip_over ?
|
||||
s_log_store_env.store_head.db_size : s_log_store_env.store_head.offset;
|
||||
|
||||
if (s_log_store_env.store_status & APP_LOG_STORE_BUSY_BIT) {
|
||||
return;
|
||||
}
|
||||
|
||||
s_log_store_env.store_status |= APP_LOG_STORE_BUSY_BIT;
|
||||
if (s_log_store_ops.flash_read && need_dump_size)
|
||||
{
|
||||
uint32_t align_num = ALIGN_NUM(APP_LOG_STORE_ONECE_OP_SIZE, need_dump_size);
|
||||
|
||||
if (s_log_store_ops.flash_read) {
|
||||
uint32_t align_num = ALIGN_NUM(APP_LOG_STORE_ONECE_OP_SIZE, s_log_store_env.store_head.offset);
|
||||
if (align_num != s_log_store_env.store_head.offset &&
|
||||
(s_log_store_dump_offset + APP_LOG_STORE_ONECE_OP_SIZE) == align_num) {
|
||||
dump_len = (s_log_store_env.store_head.offset + APP_LOG_STORE_ONECE_OP_SIZE - align_num);
|
||||
} else {
|
||||
if (align_num != need_dump_size &&
|
||||
(s_log_store_dump_offset + APP_LOG_STORE_ONECE_OP_SIZE) == align_num)
|
||||
{
|
||||
dump_len = (need_dump_size + APP_LOG_STORE_ONECE_OP_SIZE - align_num);
|
||||
}
|
||||
else
|
||||
{
|
||||
dump_len = APP_LOG_STORE_ONECE_OP_SIZE;
|
||||
}
|
||||
|
||||
s_log_store_ops.flash_read(s_log_store_dump_offset + s_log_store_env.store_head.db_addr, dump_buffer, dump_len);
|
||||
|
||||
if (s_log_store_dump_cb) {
|
||||
s_log_store_dump_cb(dump_buffer, dump_len);
|
||||
s_log_store_env.store_status &= ~APP_LOG_STORE_DUMP_READY_BIT;
|
||||
|
||||
s_log_store_dump_offset += dump_len;
|
||||
if (need_dump_size == s_log_store_dump_offset)
|
||||
{
|
||||
s_log_store_dump_offset = 0;
|
||||
s_log_store_env.store_status &= ~APP_LOG_STORE_DUMP_BIT;
|
||||
}
|
||||
|
||||
if (s_log_dump_cbs->dump_process_cb)
|
||||
{
|
||||
s_log_dump_cbs->dump_process_cb(dump_buffer, dump_len);
|
||||
}
|
||||
|
||||
s_log_store_dump_offset += dump_len;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
s_log_store_env.store_status &= ~APP_LOG_STORE_DUMP_BIT;
|
||||
s_log_store_env.store_status |= APP_LOG_STORE_DUMP_READY_BIT;
|
||||
}
|
||||
|
||||
if (s_log_store_env.store_head.db_size == s_log_store_dump_offset) {
|
||||
s_log_store_dump_offset = 0;
|
||||
}
|
||||
|
||||
if (s_log_store_env.store_head.offset == s_log_store_dump_offset) {
|
||||
s_log_store_dump_offset = 0;
|
||||
s_log_store_env.store_status &= ~APP_LOG_STORE_DUMP_BIT;
|
||||
}
|
||||
|
||||
s_log_store_env.store_status &= ~APP_LOG_STORE_BUSY_BIT;
|
||||
}
|
||||
|
||||
static void log_store_flush(void)
|
||||
{
|
||||
uint32_t items_count = 0;
|
||||
|
||||
if (!s_log_store_env.initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
do
|
||||
{
|
||||
items_count = ring_buffer_items_count_get(&s_log_store_rbuf);
|
||||
|
||||
if (items_count)
|
||||
{
|
||||
log_store_data_flash_write();
|
||||
}
|
||||
} while (items_count >= APP_LOG_STORE_ONECE_OP_SIZE);
|
||||
}
|
||||
|
||||
static void log_dump_ready(void)
|
||||
{
|
||||
uint32_t log_length;
|
||||
log_store_flush();
|
||||
|
||||
// get length and send
|
||||
if (s_log_dump_cbs->dump_start_cb)
|
||||
{
|
||||
log_length = s_log_store_env.store_head.flip_over ?
|
||||
s_log_store_env.store_head.db_size : s_log_store_env.store_head.offset;
|
||||
s_log_dump_cbs->dump_start_cb(log_length);
|
||||
}
|
||||
}
|
||||
|
||||
static void log_store_clear(void)
|
||||
{
|
||||
s_log_store_env.store_head.offset = 0;
|
||||
s_log_store_env.store_head.flip_over = 0;
|
||||
ring_buffer_clean(&s_log_store_rbuf);
|
||||
|
||||
log_store_head_update(s_log_store_env.head_nv_tag, &s_log_store_env.store_head);
|
||||
|
||||
s_log_store_dump_offset = 0;
|
||||
s_log_store_env.store_status = APP_LOG_STORE_DUMP_READY_BIT;
|
||||
}
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
@@ -271,46 +322,61 @@ uint16_t app_log_store_init(app_log_store_info_t *p_info, app_log_store_op_t *p_
|
||||
{
|
||||
uint16_t head_len = sizeof(log_store_head_t);
|
||||
|
||||
if (s_log_store_env.initialized) {
|
||||
if (s_log_store_env.initialized)
|
||||
{
|
||||
return SDK_ERR_DISALLOWED;
|
||||
}
|
||||
|
||||
if (p_info == NULL ||
|
||||
p_op_func == NULL ||
|
||||
p_op_func->flash_init == NULL ||
|
||||
p_op_func->flash_read == NULL ||
|
||||
p_op_func->flash_write == NULL ||
|
||||
p_op_func->flash_erase == NULL ||
|
||||
p_info->db_size == 0 ||
|
||||
p_info->blk_size == 0 ||
|
||||
(p_info->db_addr % p_info->blk_size) != 0) {
|
||||
if (NULL == p_info
|
||||
|| NULL == p_op_func
|
||||
|| NULL == p_op_func->flash_init
|
||||
|| NULL == p_op_func->flash_read
|
||||
|| NULL == p_op_func->flash_write
|
||||
|| NULL == p_op_func->flash_erase
|
||||
|| 0 == p_info->db_size
|
||||
|| 0 == p_info->blk_size
|
||||
|| 0 != (p_info->db_addr % p_info->blk_size))
|
||||
{
|
||||
return SDK_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
nvds_get(p_info->nv_tag, &head_len, (uint8_t *)&s_log_store_env.store_head);
|
||||
|
||||
if (!log_store_head_check(&s_log_store_env.store_head, p_info->db_addr, p_info->db_size)) {
|
||||
if (!log_store_head_check(&s_log_store_env.store_head, p_info->db_addr, p_info->db_size))
|
||||
{
|
||||
s_log_store_env.store_head.magic = APP_LOG_STORE_MAGIC;
|
||||
s_log_store_env.store_head.db_addr = p_info->db_addr;
|
||||
s_log_store_env.store_head.db_size = p_info->db_size;
|
||||
s_log_store_env.store_head.offset = 0;
|
||||
s_log_store_env.store_head.flip_over = 0;
|
||||
|
||||
if (!log_store_head_update(p_info->nv_tag, &s_log_store_env.store_head)) {
|
||||
if (!log_store_head_update(p_info->nv_tag, &s_log_store_env.store_head))
|
||||
{
|
||||
return SDK_ERR_SDK_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
ring_buffer_init(&s_log_store_rbuf, s_log_store_cache, APP_LOG_STORE_CACHE_SIZE);
|
||||
|
||||
memcpy_s(&s_log_store_ops, sizeof (s_log_store_ops), p_op_func, sizeof(s_log_store_ops));
|
||||
memcpy(&s_log_store_ops, p_op_func, sizeof(s_log_store_ops));
|
||||
|
||||
s_log_store_env.head_nv_tag = p_info->nv_tag;
|
||||
s_log_store_env.blk_size = p_info->blk_size;
|
||||
s_log_store_env.initialized = true;
|
||||
s_log_store_env.store_status |= APP_LOG_STORE_DUMP_READY_BIT;
|
||||
|
||||
p_op_func->flash_init();
|
||||
|
||||
if (APP_LOG_STORE_CACHE_SIZE != s_log_store_rbuf.buffer_size)
|
||||
{
|
||||
ring_buffer_init(&s_log_store_rbuf, s_log_store_cache, APP_LOG_STORE_CACHE_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s_log_store_ops.sem_give)
|
||||
{
|
||||
s_log_store_ops.sem_give();
|
||||
}
|
||||
}
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -319,17 +385,13 @@ uint16_t app_log_store_save(const uint8_t *p_data, const uint16_t length)
|
||||
{
|
||||
uint8_t time_encode[APP_LOG_STORE_TIME_SIZE] = APP_LOG_STORE_TIME_DEFAULT;
|
||||
|
||||
if (!s_log_store_env.initialized) {
|
||||
if (!s_log_store_env.initialized)
|
||||
{
|
||||
return SDK_ERR_DISALLOWED;
|
||||
}
|
||||
|
||||
if (s_log_store_env.store_status & APP_LOG_STORE_BUSY_BIT) {
|
||||
return SDK_ERR_BUSY;
|
||||
}
|
||||
|
||||
s_log_store_env.store_status |= APP_LOG_STORE_BUSY_BIT;
|
||||
|
||||
if (s_log_store_ops.time_get) {
|
||||
if (s_log_store_ops.time_get)
|
||||
{
|
||||
log_store_time_stamp_encode(time_encode, APP_LOG_STORE_TIME_SIZE);
|
||||
time_encode[APP_LOG_STORE_TIME_SIZE - 1] = ' ';
|
||||
}
|
||||
@@ -337,78 +399,60 @@ uint16_t app_log_store_save(const uint8_t *p_data, const uint16_t length)
|
||||
ring_buffer_write(&s_log_store_rbuf, time_encode, APP_LOG_STORE_TIME_SIZE);
|
||||
ring_buffer_write(&s_log_store_rbuf, p_data, length);
|
||||
|
||||
if (ring_buffer_items_count_get(&s_log_store_rbuf >= APP_LOG_STORE_ONECE_OP_SIZE)) {
|
||||
if ((APP_LOG_STORE_ONECE_OP_SIZE <= ring_buffer_items_count_get(&s_log_store_rbuf)) &&
|
||||
!(s_log_store_env.store_status & APP_LOG_STORE_DUMP_BIT))
|
||||
{
|
||||
s_log_store_env.store_status |= APP_LOG_STORE_SAVE_BIT;
|
||||
#if APP_LOG_STORE_RUN_ON_OS
|
||||
log_store_to_flash();
|
||||
#endif
|
||||
if (s_log_store_ops.sem_give)
|
||||
{
|
||||
s_log_store_ops.sem_give();
|
||||
}
|
||||
}
|
||||
|
||||
s_log_store_env.store_status &= ~APP_LOG_STORE_BUSY_BIT;
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void app_log_store_flush(void)
|
||||
uint16_t app_log_store_dump(app_log_dump_cbs_t * p_dump_cbs)
|
||||
{
|
||||
uint32_t items_count = 0;
|
||||
|
||||
if (!s_log_store_env.initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
items_count = ring_buffer_items_count_get(&s_log_store_rbuf);
|
||||
if (items_count) {
|
||||
log_store_data_flash_write();
|
||||
}
|
||||
} while (items_count >= APP_LOG_STORE_ONECE_OP_SIZE);
|
||||
}
|
||||
|
||||
uint16_t app_log_store_dump(app_log_store_dump_cb_t dump_cb)
|
||||
{
|
||||
if (!s_log_store_env.initialized) {
|
||||
if (!s_log_store_env.initialized)
|
||||
{
|
||||
return SDK_ERR_DISALLOWED;
|
||||
}
|
||||
|
||||
if (s_log_store_env.store_status & APP_LOG_STORE_DUMP_BIT) {
|
||||
if (s_log_store_env.store_status & APP_LOG_STORE_DUMP_BIT)
|
||||
{
|
||||
return SDK_ERR_BUSY;
|
||||
}
|
||||
|
||||
if (dump_cb == NULL) {
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
|
||||
s_log_store_dump_cb = dump_cb;
|
||||
|
||||
app_log_store_flush();
|
||||
|
||||
if (s_log_store_env.store_head.flip_over == 0 && s_log_store_env.store_head.offset == 0) {
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
if (s_log_store_env.store_head.flip_over) {
|
||||
uint32_t align_num;
|
||||
|
||||
align_num = ALIGN_NUM(s_log_store_env.blk_size, s_log_store_env.store_head.offset);
|
||||
|
||||
s_log_store_dump_offset = align_num >= s_log_store_env.store_head.db_size ? 0 : align_num;
|
||||
} else {
|
||||
s_log_store_dump_offset = 0;
|
||||
}
|
||||
|
||||
s_log_dump_cbs = p_dump_cbs;
|
||||
s_log_store_env.store_status |= APP_LOG_STORE_DUMP_START_BIT;
|
||||
s_log_store_env.store_status |= APP_LOG_STORE_DUMP_BIT;
|
||||
if (s_log_store_ops.sem_give)
|
||||
{
|
||||
s_log_store_ops.sem_give();
|
||||
}
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
void app_log_store_clear(void)
|
||||
uint16_t app_log_store_clear(void)
|
||||
{
|
||||
s_log_store_env.store_head.offset = 0;
|
||||
s_log_store_env.store_head.flip_over = 0;
|
||||
if (!s_log_store_env.initialized)
|
||||
{
|
||||
return SDK_ERR_DISALLOWED;
|
||||
}
|
||||
s_log_store_env.store_status |= APP_LOG_STORE_CLEAR_BIT;
|
||||
if (s_log_store_ops.sem_give)
|
||||
{
|
||||
s_log_store_ops.sem_give();
|
||||
}
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
log_store_head_update(s_log_store_env.head_nv_tag, &s_log_store_env.store_head);
|
||||
void app_log_status_reset(void)
|
||||
{
|
||||
s_log_store_dump_offset = 0;
|
||||
s_log_store_env.store_status = APP_LOG_STORE_DUMP_READY_BIT;
|
||||
}
|
||||
|
||||
bool app_log_store_dump_ongoing(void)
|
||||
@@ -416,17 +460,52 @@ bool app_log_store_dump_ongoing(void)
|
||||
return (s_log_store_env.store_status & APP_LOG_STORE_DUMP_BIT) ? true : false;
|
||||
}
|
||||
|
||||
void app_log_dump_continue(void)
|
||||
{
|
||||
s_log_store_env.store_status |= APP_LOG_STORE_DUMP_READY_BIT;
|
||||
|
||||
if (s_log_store_env.store_status & APP_LOG_STORE_DUMP_BIT)
|
||||
{
|
||||
if (s_log_store_ops.sem_give)
|
||||
{
|
||||
s_log_store_ops.sem_give();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s_log_dump_cbs->dump_finish_cb)
|
||||
s_log_dump_cbs->dump_finish_cb();
|
||||
}
|
||||
}
|
||||
|
||||
void app_log_store_schedule(void)
|
||||
{
|
||||
#if APP_LOG_STORE_RUN_ON_OS == 0
|
||||
if (s_log_store_env.store_status & APP_LOG_STORE_SAVE_BIT) {
|
||||
if (s_log_store_ops.sem_take)
|
||||
{
|
||||
s_log_store_ops.sem_take();
|
||||
}
|
||||
|
||||
if (s_log_store_env.store_status & APP_LOG_STORE_CLEAR_BIT)
|
||||
{
|
||||
log_store_clear();
|
||||
}
|
||||
|
||||
if (s_log_store_env.store_status & APP_LOG_STORE_SAVE_BIT)
|
||||
{
|
||||
log_store_to_flash();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (s_log_store_env.store_status & APP_LOG_STORE_DUMP_BIT) {
|
||||
if ((s_log_store_env.store_status & APP_LOG_STORE_DUMP_BIT) && (s_log_store_env.store_status & APP_LOG_STORE_DUMP_READY_BIT))
|
||||
{
|
||||
if (s_log_store_env.store_status & APP_LOG_STORE_DUMP_START_BIT)
|
||||
{
|
||||
log_dump_ready();
|
||||
s_log_store_env.store_status &= ~APP_LOG_STORE_DUMP_START_BIT;
|
||||
}
|
||||
|
||||
log_dump_from_flash();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Executable → Regular
+35
-15
@@ -40,7 +40,7 @@
|
||||
|
||||
#include "custom_config.h"
|
||||
#if APP_LOG_STORE_ENABLE
|
||||
#include "gr55xx_sys.h"
|
||||
#include "grx_sys.h"
|
||||
#include "ring_buffer.h"
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
@@ -61,16 +61,20 @@
|
||||
* @{
|
||||
*/
|
||||
/**@brief APP LOG Store flash data dump callback type. */
|
||||
typedef void (*app_log_store_dump_cb_t)(uint8_t *p_data, uint16_t len);
|
||||
typedef void (*app_log_store_dump_process_cb_t)(uint8_t *p_data, uint16_t len);
|
||||
typedef void (*app_log_store_dump_start_cb_t)(uint32_t len);
|
||||
typedef void (*app_log_store_dump_finish_cb_t)(void);
|
||||
typedef void (*app_log_sem_process)(void);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup APP_LOG_STORE_STRUCT Structures
|
||||
* @{
|
||||
*/
|
||||
/**@brief The date and time structure. The packed size is 7 bytes. */
|
||||
typedef struct {
|
||||
uint16_t year; /**< Year time element. */
|
||||
/**@brief The date and time structure. The packed size is 7 bytes. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t year; /**< Year time element. */
|
||||
uint8_t month; /**< Month time element. */
|
||||
uint8_t day; /**< Day time element. */
|
||||
uint8_t hour; /**< Hour time element. */
|
||||
@@ -80,16 +84,20 @@ typedef struct {
|
||||
} app_log_store_time_t;
|
||||
|
||||
/**@brief App log store operation functions. */
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
bool (*flash_init)(void); /**< Flash init. */
|
||||
bool (*flash_erase)(const uint32_t addr, const uint32_t size); /**< Flash erase. */
|
||||
uint32_t (*flash_read)(const uint32_t addr, uint8_t *buf, const uint32_t size); /**< Flash read. */
|
||||
uint32_t (*flash_write)(const uint32_t addr, const uint8_t *buf, const uint32_t size); /**< Flash write. */
|
||||
void (*time_get)(app_log_store_time_t *p_time); /**< Get real time. */
|
||||
app_log_sem_process sem_give;
|
||||
app_log_sem_process sem_take;
|
||||
} app_log_store_op_t;
|
||||
|
||||
/**@brief App log store init stucture. */
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
uint16_t nv_tag; /**< NVDS Tag for app log store env. */
|
||||
uint32_t db_addr; /**< Start address of app log db flash. */
|
||||
uint32_t db_size; /**< Size of app log db flash. */
|
||||
@@ -97,6 +105,15 @@ typedef struct {
|
||||
} app_log_store_info_t;
|
||||
/** @} */
|
||||
|
||||
/**@brief App log store dump stucture. */
|
||||
typedef struct
|
||||
{
|
||||
app_log_store_dump_process_cb_t dump_process_cb; /**< App log store dump callback. */
|
||||
app_log_store_dump_start_cb_t dump_start_cb; /**< App log store dump start callback. */
|
||||
app_log_store_dump_finish_cb_t dump_finish_cb; /**< App log store dump finish callback. */
|
||||
} app_log_dump_cbs_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup APP_LOG_STORE_FUNCTION Functions
|
||||
* @{
|
||||
@@ -134,21 +151,15 @@ uint16_t app_log_store_save(const uint8_t *p_data, uint16_t length);
|
||||
* @return Result of dump.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
uint16_t app_log_store_dump(app_log_store_dump_cb_t dump_cb);
|
||||
uint16_t app_log_store_dump(app_log_dump_cbs_t *p_dump_cbs);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Flush app log store cache to flash.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_log_store_flush(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief App log store clear.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_log_store_clear(void);
|
||||
uint16_t app_log_store_clear(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
@@ -157,12 +168,21 @@ void app_log_store_clear(void);
|
||||
*/
|
||||
bool app_log_store_dump_ongoing(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Continue log dump.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_log_dump_continue(void);
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief App log store schedule for save and dump.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_log_store_schedule(void);
|
||||
|
||||
/** @} */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
kernel_module("app_memory") {
|
||||
sources = [ "app_memory.c" ]
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file app_memory.c
|
||||
*
|
||||
* @brief App Memory Implementation.
|
||||
*
|
||||
*****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "app_memory.h"
|
||||
#include "utility.h"
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* DEFINE
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#define MEM_BLOCK_SIZE ALIGN_NUM(APP_MEM_ALIGN_NUM, sizeof(app_mem_block_t))
|
||||
#define BLOCK_ALLOCATED_BIT ((size_t)1 << (sizeof(size_t) * 8 - 1))
|
||||
#define BLOCK_ALLOC_SIZE_MIN (MEM_BLOCK_SIZE + APP_MEM_ALIGN_NUM)
|
||||
|
||||
/*
|
||||
* LOCAL VARIABLE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static __attribute__ ((aligned (APP_MEM_ALIGN_NUM))) uint8_t s_mem_heap[APP_MEM_HEAP_SIZE];
|
||||
|
||||
static app_mem_block_t s_start_list_node;
|
||||
static app_mem_block_t s_end_list_node;
|
||||
static size_t s_curr_free_bytes;
|
||||
static size_t s_ever_free_bytes_min;
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static void app_mem_init(void)
|
||||
{
|
||||
app_mem_block_t *p_fir_free_block;
|
||||
|
||||
s_start_list_node.p_next_free_block = (void *)s_mem_heap;
|
||||
s_start_list_node.block_size = 0;
|
||||
|
||||
|
||||
s_end_list_node.p_next_free_block = NULL;
|
||||
s_end_list_node.block_size = 0;
|
||||
|
||||
p_fir_free_block = (void *)s_mem_heap;
|
||||
|
||||
p_fir_free_block->p_next_free_block = &s_end_list_node;
|
||||
p_fir_free_block->block_size = APP_MEM_HEAP_SIZE;
|
||||
|
||||
s_curr_free_bytes = p_fir_free_block->block_size;
|
||||
s_ever_free_bytes_min = p_fir_free_block->block_size;
|
||||
}
|
||||
|
||||
|
||||
static void free_block_node_insert(app_mem_block_t *p_insert_node)
|
||||
{
|
||||
app_mem_block_t *p_iterator_node = &s_start_list_node;
|
||||
|
||||
while (p_iterator_node->p_next_free_block < p_insert_node &&
|
||||
NULL != p_iterator_node->p_next_free_block->p_next_free_block)
|
||||
{
|
||||
p_iterator_node = p_iterator_node->p_next_free_block;
|
||||
}
|
||||
|
||||
|
||||
if (((uint8_t *)p_iterator_node + p_iterator_node->block_size) == (uint8_t *)p_insert_node)
|
||||
{
|
||||
p_iterator_node->block_size += p_insert_node->block_size;
|
||||
p_insert_node = p_iterator_node;
|
||||
}
|
||||
|
||||
if (((uint8_t *)p_insert_node + p_insert_node->block_size) == (uint8_t *)p_iterator_node->p_next_free_block)
|
||||
{
|
||||
if (p_iterator_node->p_next_free_block != &s_end_list_node)
|
||||
{
|
||||
p_insert_node->block_size += p_iterator_node->p_next_free_block->block_size;
|
||||
p_insert_node->p_next_free_block = p_iterator_node->p_next_free_block->p_next_free_block;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_insert_node->p_next_free_block = &s_end_list_node;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p_insert_node->p_next_free_block = p_iterator_node->p_next_free_block;
|
||||
}
|
||||
|
||||
if (p_iterator_node != p_insert_node)
|
||||
{
|
||||
p_iterator_node->p_next_free_block = p_insert_node;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void *app_malloc(size_t size)
|
||||
{
|
||||
app_mem_block_t *p_block;
|
||||
app_mem_block_t *p_pre_block;
|
||||
app_mem_block_t *p_new_block;
|
||||
void *return_ptr = NULL;
|
||||
|
||||
APP_MEM_LOCK();
|
||||
|
||||
if (NULL == s_start_list_node.p_next_free_block)
|
||||
{
|
||||
app_mem_init();
|
||||
}
|
||||
|
||||
if (0 == (size & BLOCK_ALLOCATED_BIT) && 0 != size)
|
||||
{
|
||||
size += MEM_BLOCK_SIZE;
|
||||
size = ALIGN_NUM(APP_MEM_ALIGN_NUM, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
return return_ptr;
|
||||
}
|
||||
|
||||
if (size > 0 && size < s_curr_free_bytes)
|
||||
{
|
||||
p_pre_block = &s_start_list_node;
|
||||
p_block = s_start_list_node.p_next_free_block;
|
||||
|
||||
while ((p_block->block_size < size) && (NULL != p_block->p_next_free_block))
|
||||
{
|
||||
p_pre_block = p_block;
|
||||
p_block = p_block->p_next_free_block;
|
||||
}
|
||||
|
||||
if (p_block != &s_end_list_node)
|
||||
{
|
||||
return_ptr = (void *)((uint8_t *)p_pre_block->p_next_free_block + MEM_BLOCK_SIZE);
|
||||
p_pre_block->p_next_free_block = p_block->p_next_free_block;
|
||||
|
||||
if ((p_block->block_size - size) > BLOCK_ALLOC_SIZE_MIN)
|
||||
{
|
||||
p_new_block = (void *)((uint8_t *)p_block + size);
|
||||
p_new_block->block_size = p_block->block_size - size;
|
||||
p_block->block_size = size;
|
||||
|
||||
free_block_node_insert(p_new_block);
|
||||
}
|
||||
|
||||
s_curr_free_bytes -= p_block->block_size;
|
||||
|
||||
if (s_curr_free_bytes < s_ever_free_bytes_min)
|
||||
{
|
||||
s_ever_free_bytes_min = s_curr_free_bytes;
|
||||
}
|
||||
|
||||
p_block->block_size |= BLOCK_ALLOCATED_BIT;
|
||||
p_block->p_next_free_block = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
APP_MEM_UNLOCK();
|
||||
|
||||
return return_ptr;
|
||||
}
|
||||
|
||||
|
||||
void app_free(void *ptr)
|
||||
{
|
||||
app_mem_block_t *p_block;
|
||||
|
||||
if (NULL == ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
APP_MEM_LOCK();
|
||||
|
||||
p_block = (app_mem_block_t *)((uint8_t *)ptr - MEM_BLOCK_SIZE);
|
||||
|
||||
|
||||
if (p_block->block_size & BLOCK_ALLOCATED_BIT)
|
||||
{
|
||||
if (NULL == p_block->p_next_free_block)
|
||||
{
|
||||
p_block->block_size &= ~BLOCK_ALLOCATED_BIT;
|
||||
|
||||
s_curr_free_bytes += p_block->block_size;
|
||||
|
||||
free_block_node_insert(p_block);
|
||||
}
|
||||
}
|
||||
|
||||
APP_MEM_UNLOCK();
|
||||
}
|
||||
|
||||
void *app_realloc(void *ptr, size_t size)
|
||||
{
|
||||
app_mem_block_t *p_block;
|
||||
void *p_realloc_ptr;
|
||||
size_t block_size;
|
||||
size_t copy_size;
|
||||
|
||||
p_realloc_ptr = app_malloc(size);
|
||||
if (p_realloc_ptr)
|
||||
{
|
||||
APP_MEM_LOCK();
|
||||
p_block = (app_mem_block_t *)((uint8_t *)ptr - MEM_BLOCK_SIZE);
|
||||
block_size = (p_block->block_size & ~BLOCK_ALLOCATED_BIT);
|
||||
copy_size = (block_size - MEM_BLOCK_SIZE) > size ? size : (block_size - MEM_BLOCK_SIZE);
|
||||
memcpy(p_realloc_ptr, (uint8_t *)ptr, copy_size);
|
||||
APP_MEM_UNLOCK();
|
||||
app_free(ptr);
|
||||
return p_realloc_ptr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t app_mem_curr_free_size_get(void)
|
||||
{
|
||||
return s_curr_free_bytes;
|
||||
}
|
||||
|
||||
|
||||
size_t app_mem_ever_free_min_size_get(void)
|
||||
{
|
||||
return s_ever_free_bytes_min;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file app_memory.h
|
||||
*
|
||||
* @brief App Memory API
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __APP_MEMORY_H__
|
||||
#define __APP_MEMORY_H__
|
||||
|
||||
#include "grx_hal.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @defgroup APP_MEMORY_MAROC Defines
|
||||
* @{
|
||||
*/
|
||||
#ifndef APP_MEM_ALIGN_NUM
|
||||
#define APP_MEM_ALIGN_NUM 4 /**< ALIGN number: 4 byte. */
|
||||
#endif
|
||||
|
||||
#ifndef APP_MEM_HEAP_SIZE
|
||||
#define APP_MEM_HEAP_SIZE (4 * 1024) /**< Total app memory heap size. */
|
||||
#endif
|
||||
|
||||
#define APP_MEM_LOCK() GLOBAL_EXCEPTION_DISABLE() /**< App memory lock. */
|
||||
#define APP_MEM_UNLOCK() GLOBAL_EXCEPTION_ENABLE() /**< App memory unlock. */
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup APP_MEMORY_STRUCT Structures
|
||||
* @{
|
||||
*/
|
||||
/**@brief App Memory Block Information */
|
||||
typedef struct mem_block_info
|
||||
{
|
||||
struct mem_block_info *p_next_free_block; /**< Pointer to next free block. */
|
||||
size_t block_size; /**< Size of block. */
|
||||
} app_mem_block_t;
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup APP_MEMORY_FUNCTION Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Malloc a block memory.
|
||||
*
|
||||
* @param[in] size: Size of memory needed to be alloced.
|
||||
*
|
||||
* @return Pointer to alloced memory.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void *app_malloc(size_t size);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Realloc a block memory.
|
||||
*
|
||||
* @param[in] ptr: Pointer to memory had been alloced.
|
||||
* @param[in] size: Size of memory needed to be realloced.
|
||||
*
|
||||
* @return Pointer to realloced memory.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void *app_realloc(void *ptr, size_t size);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Free a block memory.
|
||||
*
|
||||
* @param[in] ptr: Pointer to memory needed to be free.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_free(void *ptr);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Get current free size of app memory.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
size_t app_mem_curr_free_size_get(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Get ever min free size of app memory.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
size_t app_mem_ever_free_min_size_get(void);
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
kernel_module("app_queue") {
|
||||
sources = [ "app_queue.c" ]
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file app_queue.c
|
||||
*
|
||||
* @brief APP Queue function Implementation.
|
||||
*
|
||||
*****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "app_queue.h"
|
||||
#include "grx_hal.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* DEFINES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#define APP_QUEUE_LOCK() LOCAL_INT_DISABLE(BLE_IRQn)
|
||||
#define APP_QUEUE_UNLOCK() LOCAL_INT_RESTORE()
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t app_queue_init(app_queue_t *p_queue, void *p_buffer, uint16_t queue_size, uint16_t element_size)
|
||||
{
|
||||
if (NULL == p_queue || NULL == p_buffer)
|
||||
{
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
|
||||
p_queue->element_size = element_size;
|
||||
p_queue->queue_size = queue_size;
|
||||
p_queue->p_buffer = p_buffer;
|
||||
p_queue->start_idx = 0;
|
||||
p_queue->end_idx = 0;
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
sdk_err_t app_queue_push(app_queue_t *p_queue, void const *p_elemment)
|
||||
{
|
||||
bool is_full;
|
||||
uint16_t wr_idx;
|
||||
void *p_wr_pos;
|
||||
sdk_err_t error_code = SDK_SUCCESS;
|
||||
|
||||
if (NULL == p_queue || NULL == p_elemment)
|
||||
{
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
|
||||
APP_QUEUE_LOCK();
|
||||
|
||||
is_full = app_queue_is_full(p_queue);
|
||||
|
||||
if (is_full)
|
||||
{
|
||||
error_code = SDK_ERR_NO_RESOURCES;
|
||||
}
|
||||
else
|
||||
{
|
||||
wr_idx = p_queue->end_idx;
|
||||
p_wr_pos = (void *)((size_t)p_queue->p_buffer + wr_idx * p_queue->element_size);
|
||||
p_queue->end_idx = app_queue_next_idx_get(p_queue->end_idx, p_queue->queue_size);
|
||||
|
||||
memcpy(p_wr_pos, p_elemment, p_queue->element_size);
|
||||
}
|
||||
|
||||
APP_QUEUE_UNLOCK();
|
||||
|
||||
return error_code;
|
||||
}
|
||||
|
||||
uint16_t app_queue_multi_push(app_queue_t *p_queue, void const *p_elemment, uint16_t amount)
|
||||
{
|
||||
uint16_t stored_num = 0;
|
||||
uint16_t surplus_space = 0;
|
||||
uint16_t over_flow = 0;
|
||||
uint16_t wr_idx;
|
||||
void *p_wr_pos;
|
||||
void *p_head_pos;
|
||||
|
||||
if (NULL == p_elemment || 0 == amount)
|
||||
{
|
||||
stored_num = 0;
|
||||
}
|
||||
|
||||
APP_QUEUE_LOCK();
|
||||
|
||||
surplus_space = app_queue_surplus_space_get(p_queue);
|
||||
wr_idx = p_queue->end_idx;
|
||||
p_wr_pos = (void *)((size_t)p_queue->p_buffer + wr_idx * p_queue->element_size);
|
||||
p_head_pos = (void *)((size_t)p_queue->p_buffer);
|
||||
|
||||
stored_num = amount > surplus_space ? surplus_space : amount;
|
||||
|
||||
if (p_queue->start_idx <= p_queue->end_idx)
|
||||
{
|
||||
if (p_queue->end_idx + amount >= p_queue->queue_size)
|
||||
{
|
||||
over_flow = p_queue->end_idx + amount - p_queue->queue_size;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(p_wr_pos, p_elemment, p_queue->element_size * (stored_num - over_flow));
|
||||
memcpy(p_head_pos,
|
||||
(void const *)((size_t)p_elemment + p_queue->element_size * (stored_num - over_flow)),
|
||||
p_queue->element_size * over_flow);
|
||||
|
||||
wr_idx += stored_num;
|
||||
|
||||
if (wr_idx >= p_queue->queue_size)
|
||||
{
|
||||
wr_idx -= p_queue->queue_size;
|
||||
}
|
||||
|
||||
p_queue->end_idx = wr_idx;
|
||||
|
||||
APP_QUEUE_UNLOCK();
|
||||
|
||||
return stored_num;
|
||||
}
|
||||
|
||||
sdk_err_t app_queue_peek(app_queue_t *p_queue, void *p_elemment)
|
||||
{
|
||||
uint16_t peek_idx = 0;
|
||||
void *p_peek_pos = NULL;
|
||||
sdk_err_t error_code = SDK_SUCCESS;
|
||||
|
||||
if (NULL == p_queue || NULL == p_elemment)
|
||||
{
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
|
||||
APP_QUEUE_LOCK();
|
||||
|
||||
if (app_queue_is_empty(p_queue))
|
||||
{
|
||||
error_code = SDK_ERR_LIST_ITEM_NOT_FOUND;
|
||||
}
|
||||
|
||||
peek_idx = p_queue->start_idx;
|
||||
p_peek_pos = (void *)((size_t)p_queue->p_buffer + peek_idx * p_queue->element_size);
|
||||
|
||||
memcpy(p_elemment, p_peek_pos, p_queue->element_size);
|
||||
|
||||
APP_QUEUE_UNLOCK();
|
||||
|
||||
return error_code;
|
||||
}
|
||||
|
||||
sdk_err_t app_queue_pop(app_queue_t *p_queue, void *p_elemment)
|
||||
{
|
||||
uint16_t peek_idx = 0;
|
||||
void *p_peek_pos = NULL;
|
||||
sdk_err_t error_code = SDK_SUCCESS;
|
||||
|
||||
if (NULL == p_queue || NULL == p_elemment)
|
||||
{
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
|
||||
APP_QUEUE_LOCK();
|
||||
|
||||
if (app_queue_is_empty(p_queue))
|
||||
{
|
||||
error_code = SDK_ERR_LIST_ITEM_NOT_FOUND;
|
||||
}
|
||||
else
|
||||
{
|
||||
peek_idx = p_queue->start_idx;
|
||||
p_peek_pos = (void *)((size_t)p_queue->p_buffer + peek_idx * p_queue->element_size);
|
||||
p_queue->start_idx = app_queue_next_idx_get(p_queue->start_idx, p_queue->queue_size);
|
||||
|
||||
memcpy(p_elemment, p_peek_pos, p_queue->element_size);
|
||||
}
|
||||
|
||||
APP_QUEUE_UNLOCK();
|
||||
|
||||
return error_code;
|
||||
}
|
||||
|
||||
uint16_t app_queue_surplus_space_get(app_queue_t *p_queue)
|
||||
{
|
||||
uint16_t start_idx = p_queue->start_idx;
|
||||
uint16_t end_idx = p_queue->end_idx;
|
||||
uint16_t queue_size = p_queue->queue_size;
|
||||
uint16_t surplus_space = 0;
|
||||
|
||||
APP_QUEUE_LOCK();
|
||||
|
||||
if (start_idx <= end_idx)
|
||||
{
|
||||
surplus_space = queue_size - end_idx + start_idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
surplus_space = start_idx - end_idx - 1;
|
||||
}
|
||||
|
||||
APP_QUEUE_UNLOCK();
|
||||
|
||||
return surplus_space;
|
||||
}
|
||||
|
||||
uint16_t app_queue_items_count_get(app_queue_t *p_queue)
|
||||
{
|
||||
uint16_t start_idx = p_queue->start_idx;
|
||||
uint16_t end_idx = p_queue->end_idx;
|
||||
uint16_t queue_size = p_queue->queue_size;
|
||||
uint16_t items_count = 0;
|
||||
|
||||
if (NULL == p_queue)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
APP_QUEUE_LOCK();
|
||||
|
||||
if (start_idx <= end_idx)
|
||||
{
|
||||
items_count = end_idx - start_idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
items_count = queue_size - start_idx + end_idx;
|
||||
}
|
||||
|
||||
APP_QUEUE_UNLOCK();
|
||||
|
||||
return items_count;
|
||||
}
|
||||
|
||||
void app_queue_clean(app_queue_t *p_queue)
|
||||
{
|
||||
APP_QUEUE_LOCK();
|
||||
|
||||
p_queue->start_idx = 0;
|
||||
p_queue->end_idx = 0;
|
||||
|
||||
APP_QUEUE_UNLOCK();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file app_queue.h
|
||||
*
|
||||
* @brief Header file - APP QUEUE APIs
|
||||
*
|
||||
*****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __APP_QUEUE_H__
|
||||
#define __APP_QUEUE_H__
|
||||
|
||||
#include "grx_sys.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @defgroup APP_QUEUE_STRUCT Structures
|
||||
* @{
|
||||
*/
|
||||
/**@brief App queue instance information. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t element_size; /**< Size of app queue element. */
|
||||
uint16_t queue_size; /**< Size of app queue buffer. */
|
||||
void *p_buffer; /**< Pointer to app queue buffer. */
|
||||
uint16_t start_idx; /**< Start index of app queue. */
|
||||
uint16_t end_idx; /**< End index of app queue. */
|
||||
} app_queue_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup APP_QUEUE_FUNCTION Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Initialize one app queue instance.
|
||||
*
|
||||
* @param[in] p_queue: Pointer to app queue instance.
|
||||
* @param[in] p_buffer: Pointer to queue buffer.
|
||||
* @param[in] queue_size: Size of queue buffer(The actual queue allocation size is one more than available).
|
||||
* @param[in] element_size: Size of queue element
|
||||
*
|
||||
* @return Result of initializing app queue.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t app_queue_init(app_queue_t *p_queue, void *p_buffer, uint16_t queue_size, uint16_t element_size);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Push one element to tail of app queue.
|
||||
*
|
||||
* @param[in] p_queue: Pointer to app queue instance.
|
||||
* @param[in] p_elemment: Pointer to the element that will be stored in the queue.
|
||||
*
|
||||
* @return Result of element push.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t app_queue_push(app_queue_t *p_queue, void const *p_elemment);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Push some elements to tail of app queue.
|
||||
*
|
||||
* @param[in] p_queue: Pointer to app queue instance.
|
||||
* @param[in] p_elemment: Pointer to the elements that will be stored in the queue.
|
||||
* @param[in] amount: Amount of the elements that wants be stored in the queue.
|
||||
*
|
||||
* @return Amount of writen elements.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
uint16_t app_queue_multi_push(app_queue_t *p_queue, void const *p_elemment, uint16_t amount);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Peek one element from tail of app queue.
|
||||
*
|
||||
* @param[in] p_queue: Pointer to app queue instance.
|
||||
* @param[out] p_elemment: Pointer to where the element will be copied.
|
||||
*
|
||||
* @return Result of element peek.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t app_queue_peek(app_queue_t *p_queue, void *p_elemment);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Pop one element from tail of app queue.
|
||||
*
|
||||
* @param[in] p_queue: Pointer to app queue instance.
|
||||
* @param[out] p_elemment: Pointer to where the element will be copied.
|
||||
*
|
||||
* @return Result of element pop.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t app_queue_pop(app_queue_t *p_queue, void *p_elemment);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Get next index.
|
||||
*
|
||||
* @param[in] curr_idx: Current index.
|
||||
* @param[in] size: Size of current app queue.
|
||||
*
|
||||
* @retval Next index.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint16_t app_queue_next_idx_get(uint16_t curr_idx, uint16_t size)
|
||||
{
|
||||
return (curr_idx < size) ? (curr_idx + 1) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Check app queue is full or not.
|
||||
*
|
||||
* @param[in] p_queue: Pointer to app queue instance.
|
||||
*
|
||||
* @return Result of check.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
__STATIC_FORCEINLINE bool app_queue_is_full(app_queue_t *p_queue)
|
||||
{
|
||||
uint16_t next_idx;
|
||||
|
||||
next_idx = app_queue_next_idx_get( p_queue->end_idx, p_queue->queue_size);
|
||||
|
||||
return next_idx == p_queue->start_idx;
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Check app queue is empty or not.
|
||||
*
|
||||
* @param[in] p_queue: Pointer to app queue instance.
|
||||
*
|
||||
* @return Result of check.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
__STATIC_FORCEINLINE bool app_queue_is_empty(app_queue_t *p_queue)
|
||||
{
|
||||
return (p_queue->start_idx == p_queue->end_idx);
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Get surplus space of one app queue.
|
||||
*
|
||||
* @param[in] p_queue: Pointer to app queue instance.
|
||||
*
|
||||
* @retval Size of surplus space.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
uint16_t app_queue_surplus_space_get(app_queue_t *p_queue);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Get availdble data from one ring buffer.
|
||||
*
|
||||
* @param[in] p_queue: Pointer to app queue instance.
|
||||
*
|
||||
* @retval Count of availdble items.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
uint16_t app_queue_items_count_get(app_queue_t *p_queue);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Clean one app queue.
|
||||
*
|
||||
* @param[in] p_queue: Pointer to app queue instance.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_queue_clean(app_queue_t *p_queue);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
kernel_module("app_scheduler") {
|
||||
sources = [ "app_scheduler.c" ]
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file app_scheduler.c
|
||||
*
|
||||
* @brief App Scheduler Implementation.
|
||||
*
|
||||
*****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "app_scheduler.h"
|
||||
#include "grx_hal.h"
|
||||
#include "app_memory.h"
|
||||
|
||||
/*
|
||||
* DEFINES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#define APP_SCHEDULER_LOCK() LOCAL_INT_DISABLE(BLE_IRQn)
|
||||
#define APP_SCHEDULER_UNLOCK() LOCAL_INT_RESTORE()
|
||||
|
||||
/*
|
||||
* STRUCTURES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
/**@brief App scheduler environment variable. */
|
||||
struct app_scheduler_env_t
|
||||
{
|
||||
app_scheduler_evt_info_t *p_evt_info_buffer;
|
||||
uint16_t evt_queue_size;
|
||||
volatile uint8_t queue_start_index;
|
||||
volatile uint8_t queue_end_index;
|
||||
};
|
||||
|
||||
/*
|
||||
* LOCAL VARIABLE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static struct app_scheduler_env_t s_app_scheduler_env;
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static __INLINE uint8_t next_index_get(uint8_t index)
|
||||
{
|
||||
return (index < s_app_scheduler_env.evt_queue_size) ? (index + 1) : 0;
|
||||
}
|
||||
|
||||
static __INLINE bool is_evt_queue_full()
|
||||
{
|
||||
return next_index_get(s_app_scheduler_env.queue_end_index) == s_app_scheduler_env.queue_start_index;
|
||||
}
|
||||
|
||||
static __INLINE bool is_evt_queue_empty()
|
||||
{
|
||||
return s_app_scheduler_env.queue_end_index == s_app_scheduler_env.queue_start_index;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t app_scheduler_init(uint16_t queue_size)
|
||||
{
|
||||
if (!queue_size)
|
||||
{
|
||||
return SDK_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
s_app_scheduler_env.p_evt_info_buffer = app_malloc((queue_size + 1) * sizeof(app_scheduler_evt_info_t));
|
||||
|
||||
if (NULL == s_app_scheduler_env.p_evt_info_buffer)
|
||||
{
|
||||
return SDK_ERR_NO_RESOURCES;
|
||||
}
|
||||
|
||||
memset(s_app_scheduler_env.p_evt_info_buffer, 0, (queue_size + 1) * sizeof(app_scheduler_evt_info_t));
|
||||
|
||||
s_app_scheduler_env.evt_queue_size = queue_size;
|
||||
s_app_scheduler_env.queue_start_index = 0;
|
||||
s_app_scheduler_env.queue_end_index = 0;
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
sdk_err_t app_scheduler_evt_put(void const *p_evt_data, uint16_t evt_data_size, app_scheduler_evt_handler_t evt_handler)
|
||||
{
|
||||
sdk_err_t error_code;
|
||||
void *evt_data_ptr;
|
||||
|
||||
APP_SCHEDULER_LOCK();
|
||||
|
||||
if (!is_evt_queue_full())
|
||||
{
|
||||
s_app_scheduler_env.p_evt_info_buffer[s_app_scheduler_env.queue_end_index].evt_handler = evt_handler;
|
||||
s_app_scheduler_env.p_evt_info_buffer[s_app_scheduler_env.queue_end_index].evt_data_size = evt_data_size;
|
||||
if (p_evt_data && evt_data_size)
|
||||
{
|
||||
evt_data_ptr = app_malloc(evt_data_size);
|
||||
if (NULL == evt_data_ptr)
|
||||
{
|
||||
return SDK_ERR_NO_RESOURCES;
|
||||
}
|
||||
|
||||
memcpy(evt_data_ptr, p_evt_data, evt_data_size);
|
||||
s_app_scheduler_env.p_evt_info_buffer[s_app_scheduler_env.queue_end_index].p_evt_data = evt_data_ptr;
|
||||
}
|
||||
s_app_scheduler_env.queue_end_index = next_index_get(s_app_scheduler_env.queue_end_index);
|
||||
error_code = SDK_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
error_code = SDK_ERR_NO_RESOURCES;
|
||||
}
|
||||
|
||||
APP_SCHEDULER_UNLOCK();
|
||||
|
||||
return error_code;
|
||||
}
|
||||
|
||||
void app_scheduler_execute(void)
|
||||
{
|
||||
while(!is_evt_queue_empty())
|
||||
{
|
||||
void *p_evt_data;
|
||||
uint16_t evt_data_size;
|
||||
app_scheduler_evt_handler_t evt_handler;
|
||||
uint8_t evt_index;
|
||||
|
||||
evt_index = s_app_scheduler_env.queue_start_index;
|
||||
|
||||
p_evt_data = s_app_scheduler_env.p_evt_info_buffer[evt_index].p_evt_data;
|
||||
evt_data_size = s_app_scheduler_env.p_evt_info_buffer[evt_index].evt_data_size;
|
||||
evt_handler = s_app_scheduler_env.p_evt_info_buffer[evt_index].evt_handler;
|
||||
|
||||
if (evt_handler)
|
||||
{
|
||||
evt_handler(p_evt_data, evt_data_size);
|
||||
}
|
||||
|
||||
app_free(p_evt_data);
|
||||
|
||||
s_app_scheduler_env.queue_start_index = next_index_get(s_app_scheduler_env.queue_start_index);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file app_scheduler.h
|
||||
*
|
||||
* @brief App Scheduler API
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __APP_SCHEDULER_H__
|
||||
#define __APP_SCHEDULER_H__
|
||||
|
||||
#include "grx_sys.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @defgroup APP_SCHEDULER_TYPEDEF Typedefs
|
||||
* @{
|
||||
*/
|
||||
/**@brief APP Scheduler event handler type. */
|
||||
typedef void (*app_scheduler_evt_handler_t)(void *p_evt_data, uint16_t evt_data_size);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup APP_SCHEDULER_STRUCT Structures
|
||||
* @{
|
||||
*/
|
||||
/**@brief App scheduler event information. */
|
||||
typedef struct
|
||||
{
|
||||
app_scheduler_evt_handler_t evt_handler; /**< Event handler. */
|
||||
void *p_evt_data; /**< Pointer to event data. */
|
||||
uint16_t evt_data_size; /**< Size of event data. */
|
||||
} app_scheduler_evt_info_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup APP_SCHEDULER_FUNCTION Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Initialize app scheduler module.
|
||||
*
|
||||
* @param[in] queue_size: Event queue size.
|
||||
*
|
||||
* @return Result of initialization.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t app_scheduler_init(uint16_t queue_size);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Put an event into event queue.
|
||||
*
|
||||
* @param[in] p_evt_data: Pointer to event data.
|
||||
* @param[in] evt_data_size: Size of event data.
|
||||
* @param[in] evt_handler: Event handler.
|
||||
*
|
||||
* @return Result of put.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t app_scheduler_evt_put(void const *p_evt_data, uint16_t evt_data_size, app_scheduler_evt_handler_t evt_handler);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Executing all events.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_scheduler_execute(void);
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
kernel_module("app_timer") {
|
||||
sources = [ "app_timer.c" ]
|
||||
}
|
||||
Executable → Regular
+546
-390
File diff suppressed because it is too large
Load Diff
Executable → Regular
+77
-44
@@ -38,27 +38,34 @@
|
||||
#ifndef __APP_TIMER_H__
|
||||
#define __APP_TIMER_H__
|
||||
|
||||
#include "grx_sys.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "gr55xx_sys.h"
|
||||
|
||||
/**
|
||||
* @defgroup APP_TIMER_MAROC Defines
|
||||
* @{
|
||||
*/
|
||||
#ifndef APP_TIMER_USE_SCHEDULER
|
||||
#define APP_TIMER_USE_SCHEDULER 0 /**< Enable scheduling app_timer events to app_scheduler. */
|
||||
#endif
|
||||
/** @brief For compatibility with previous version. */
|
||||
#define app_timer_start(a, b, c) app_timer_start_api(&a, b, c)
|
||||
#define app_timer_stop(a) app_timer_stop_api(&a)
|
||||
|
||||
/** @brief App timer version difine. */
|
||||
#define APP_TIMER_VERSION 0x0200
|
||||
|
||||
/** @brief App timer assert enable define. */
|
||||
#define APP_TIMER_ASSERT_ENABLE 0
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup APP_TIMER_ENUM Enumerations
|
||||
* @{
|
||||
*/
|
||||
/**@brief App timer trigger types. */
|
||||
typedef enum {
|
||||
ATIMER_ONE_SHOT = 0x0, /**< The timer will expire only once. */
|
||||
ATIMER_REPEAT /**< The timer will restart each time it expires. */
|
||||
/** @brief App timer trigger types. */
|
||||
typedef enum
|
||||
{
|
||||
ATIMER_ONE_SHOT = 0x0, /**< The timer will expire only once. */
|
||||
ATIMER_REPEAT /**< The timer will restart each time it expires. */
|
||||
} app_timer_type_t;
|
||||
/** @} */
|
||||
|
||||
@@ -66,40 +73,36 @@ typedef enum {
|
||||
* @defgroup APP_TIMER_TYPEDEF Typedefs
|
||||
* @{
|
||||
*/
|
||||
/**@brief The timer node trigger function. */
|
||||
typedef void (*app_timer_fun_t)(uint8_t* p_ctx);
|
||||
/** @brief The timer node trigger function. */
|
||||
typedef void (*app_timer_fun_t)(void* p_ctx);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup APP_TIMER_STRUCT Structures
|
||||
* @{
|
||||
*/
|
||||
/**@brief App timer global variable. */
|
||||
typedef struct {
|
||||
uint8_t timer_node_used; /**< Timer node is used or not. */
|
||||
uint8_t timer_node_status; /**< Timer node status. */
|
||||
uint8_t next_trigger_mode; /**< Next trigger mode. */
|
||||
uint32_t original_delay; /**< Original delay (us). */
|
||||
uint32_t next_trigger_time; /**< Next trigger time. */
|
||||
uint8_t* next_trigger_callback_var; /**< Timer trigger callback argument. */
|
||||
app_timer_fun_t next_trigger_callback; /**< Timer trigger callback . */
|
||||
/** @brief App timer global variable. */
|
||||
typedef struct app_timer_s
|
||||
{
|
||||
uint8_t timer_mark;
|
||||
uint8_t timer_node_status; /**< Timer node status. */
|
||||
uint8_t timer_node_mode; /**< Next trigger mode. */
|
||||
uint64_t original_delay; /**< Original delay (us). */
|
||||
uint64_t next_shot_time;
|
||||
void* arg; /**< Timer trigger callback argument. */
|
||||
app_timer_fun_t timer_node_cb; /**< Timer trigger callback . */
|
||||
struct app_timer_s *p_next;
|
||||
} app_timer_t;
|
||||
|
||||
#if APP_TIMER_USE_SCHEDULER
|
||||
/**@brief Structure passed to app_scheduler. */
|
||||
typedef struct {
|
||||
app_timer_fun_t timeout_handler; /**< Timer timeout handler. */
|
||||
void *p_ctx; /**< Pointer to callback argument. */
|
||||
} app_timer_evt_t;
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup APP_TIMER_TYPEDEF Typedefs
|
||||
* @{
|
||||
*/
|
||||
/**@brief The timer node id. */
|
||||
typedef app_timer_t* app_timer_id_t;
|
||||
/** @brief The timer node id. */
|
||||
typedef app_timer_t app_timer_id_t;
|
||||
typedef app_timer_t* p_app_timer_id_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@@ -131,21 +134,13 @@ typedef app_timer_t* app_timer_id_t;
|
||||
*/
|
||||
sdk_err_t app_timer_create(app_timer_id_t *p_timer_id, app_timer_type_t mode, app_timer_fun_t callback);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Gets the current app timer's switching status
|
||||
* @return state 0 means stop 1 means open
|
||||
*****************************************************************************************
|
||||
*/
|
||||
uint8_t app_timer_get_status(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief To stop a existed timer in node list
|
||||
* @param[in] p_timer_id: the id of timer node
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_timer_stop(app_timer_id_t p_timer_id);
|
||||
void app_timer_stop_api(app_timer_id_t *p_timer_id);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
@@ -156,7 +151,7 @@ void app_timer_stop(app_timer_id_t p_timer_id);
|
||||
* @param[in] p_ctx : the pointer of context
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t app_timer_start(app_timer_id_t p_timer_id, uint32_t delay, uint8_t *p_ctx);
|
||||
sdk_err_t app_timer_start_api(app_timer_id_t *p_timer_id, uint32_t delay, void *p_ctx);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
@@ -169,14 +164,52 @@ sdk_err_t app_timer_delete(app_timer_id_t *p_timer_id);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Stop the currently running timer and return the running time
|
||||
*
|
||||
* @param[in] p_timer_handle: Pointer to the timer handle
|
||||
*
|
||||
* @return The time that the current timer has run
|
||||
* @brief Gets the current app timer's switching status
|
||||
* @return state 0 means stop, 1 means run
|
||||
*****************************************************************************************
|
||||
*/
|
||||
uint32_t app_timer_stop_and_ret(app_timer_id_t p_timer_id);
|
||||
uint8_t app_timer_get_status(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Set the app timer's trigger window, all timer nodes that fall within the window
|
||||
* will be triggered at the same time.
|
||||
* @param[in] window_us: new trigger window size, in us
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void app_timer_trigger_window_set(uint64_t window_us);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Get the app timer's trigger window, all timer nodes that fall within the window
|
||||
* will be triggered at the same time.
|
||||
* @return current trigger window size, in us
|
||||
*****************************************************************************************
|
||||
*/
|
||||
uint64_t app_timer_trigger_window_get(void);
|
||||
|
||||
#define IS_APP_TIMER_MODE(MODE) \
|
||||
(((MODE) == ATIMER_ONE_SHOT) || ((MODE) == ATIMER_REPEAT))
|
||||
|
||||
#define APP_TIMER_DEFINE(name, func, mode) \
|
||||
app_timer_t name = \
|
||||
{ \
|
||||
.timer_node_status = 0x0, \
|
||||
.timer_node_mode = mode, \
|
||||
.timer_node_cb = func, \
|
||||
}
|
||||
|
||||
#define APP_TIMER_QUICK_START(name, func, peido) \
|
||||
{ \
|
||||
app_timer_create(&name, ATIMER_REPEAT, func); \
|
||||
app_timer_start_api(&name, peido, &name); \
|
||||
}
|
||||
|
||||
#define APP_TIMER_QUICK_STOP(name) \
|
||||
{ \
|
||||
app_timer_stop_api(&name); \
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
kernel_module("at_cmd") {
|
||||
sources = [
|
||||
"at_cmd.c",
|
||||
"at_cmd_utils.c",
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,366 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file AT_CMD.c
|
||||
*
|
||||
* @brief AT Command implementation.
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
#include "at_cmd.h"
|
||||
#include "at_cmd_utils.h"
|
||||
#include "cmsis_compiler.h"
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* STRUCTURES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
/**@brief AT Command environment variable. */
|
||||
struct at_cmd_env_t
|
||||
{
|
||||
uint8_t cmd_num;
|
||||
at_cmd_src_t cmd_src;
|
||||
at_cmd_attr_t *p_cmd_attr;
|
||||
at_cmd_time_callback_t cmd_time_cb;
|
||||
at_cmd_cplt_callback_t cmd_cplt_cb;
|
||||
at_cmd_state_t cmd_state;
|
||||
};
|
||||
|
||||
/*
|
||||
* LOCAL VARIABLE DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
static struct at_cmd_env_t s_at_cmd_env;
|
||||
static at_cmd_parse_t s_parse_rlt;
|
||||
|
||||
static uint8_t at_cmd_inp_buff[AT_CMD_BUFFER_SIZE_MAX];
|
||||
static uint8_t at_cmd_rsp_buff[AT_CMD_BUFFER_SIZE_MAX];
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Check AT CMD input integrity.
|
||||
*
|
||||
* @param[in] p_data: Pointer to input data.
|
||||
* @param[in] length: Length of input data.
|
||||
* @param[out] p_parse_rlt: Pointer to parse result.
|
||||
*
|
||||
* @return Result of check.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static bool at_cmd_integrity_check(const uint8_t *p_data, uint16_t length, at_cmd_parse_t *p_parse_rlt)
|
||||
{
|
||||
if (0 != memcmp(p_data, "AT:", 3))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (uint8_t i = 1; i < length; i++)
|
||||
{
|
||||
if (0x0a == p_data[i] && 0x0d == p_data[i - 1])
|
||||
{
|
||||
p_parse_rlt->buff_length = i + 1;
|
||||
memcpy(p_parse_rlt->p_buff, p_data, p_parse_rlt->buff_length);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Get args of AT CMD.
|
||||
*
|
||||
* @param[out] p_parse_rlt: Pointer to parse result.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static void at_cmd_args_get(at_cmd_parse_t *p_parse_rlt)
|
||||
{
|
||||
p_parse_rlt->arg_count = 0;
|
||||
|
||||
uint16_t first_arg_idx = 0;
|
||||
|
||||
p_parse_rlt->cmd_tag_idx = 3;
|
||||
|
||||
for (uint16_t i = p_parse_rlt->cmd_tag_idx; i <= (p_parse_rlt->buff_length - 2); i++)
|
||||
{
|
||||
if (i == (p_parse_rlt->buff_length - 2))
|
||||
{
|
||||
p_parse_rlt->cmd_tag_length = i - p_parse_rlt->cmd_tag_idx;
|
||||
p_parse_rlt->arg_count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if ('=' == p_parse_rlt->p_buff[i])
|
||||
{
|
||||
p_parse_rlt->cmd_tag_length = i - p_parse_rlt->cmd_tag_idx + 1;
|
||||
first_arg_idx = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
p_parse_rlt->arg_idx[0] = first_arg_idx;
|
||||
|
||||
for (uint16_t i = first_arg_idx; i <= (p_parse_rlt->buff_length - 2); i++)
|
||||
{
|
||||
if ((':' == p_parse_rlt->p_buff[i]) || (',' == p_parse_rlt->p_buff[i]))
|
||||
{
|
||||
p_parse_rlt->arg_length[p_parse_rlt->arg_count] = i - p_parse_rlt->arg_idx[p_parse_rlt->arg_count];
|
||||
p_parse_rlt->arg_count++;
|
||||
p_parse_rlt->arg_idx[p_parse_rlt->arg_count] = i + 1;
|
||||
}
|
||||
else if (i == (p_parse_rlt->buff_length - 2))
|
||||
{
|
||||
p_parse_rlt->arg_length[p_parse_rlt->arg_count] = i - p_parse_rlt->arg_idx[p_parse_rlt->arg_count];
|
||||
p_parse_rlt->arg_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Get ID of AT CMD.
|
||||
*
|
||||
* @param[out] p_parse_rlt: Pointer to parse result.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static void at_cmd_id_get(at_cmd_parse_t *p_parse_rlt)
|
||||
{
|
||||
p_parse_rlt->cmd_id = AT_CMD_INVALID;
|
||||
|
||||
for (uint8_t i = 0; i < s_at_cmd_env.cmd_num; i++)
|
||||
{
|
||||
if (p_parse_rlt->cmd_tag_length == s_at_cmd_env.p_cmd_attr[i].cmd_tag_length)
|
||||
{
|
||||
if (0 == memcmp(&p_parse_rlt->p_buff[p_parse_rlt->cmd_tag_idx],
|
||||
s_at_cmd_env.p_cmd_attr[i].cmd_tag_str,
|
||||
p_parse_rlt->cmd_tag_length))
|
||||
{
|
||||
p_parse_rlt->cmd_id = s_at_cmd_env.p_cmd_attr[i].cmd_id;
|
||||
p_parse_rlt->cmd_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
void at_cmd_init(at_cmd_init_t *p_cmd_init)
|
||||
{
|
||||
memset(&s_at_cmd_env, 0, sizeof(s_at_cmd_env));
|
||||
memset(&s_parse_rlt, 0, sizeof(at_cmd_parse_t));
|
||||
|
||||
s_at_cmd_env.cmd_num = p_cmd_init->cmd_num;
|
||||
s_at_cmd_env.p_cmd_attr = p_cmd_init->p_cmd_attr;
|
||||
s_at_cmd_env.cmd_time_cb = p_cmd_init->cmd_time_cb;
|
||||
s_at_cmd_env.cmd_cplt_cb = p_cmd_init->cmd_cplt_cb;
|
||||
s_at_cmd_env.cmd_state = AT_CMD_IN_READY_PARSE;
|
||||
s_at_cmd_env.cmd_src = AT_CMD_SRC_UART;
|
||||
|
||||
s_parse_rlt.p_buff = at_cmd_inp_buff;
|
||||
s_parse_rlt.buff_length = 0;
|
||||
}
|
||||
|
||||
void at_cmd_parse(at_cmd_src_t cmd_src, const uint8_t *p_data, uint16_t length)
|
||||
{
|
||||
AT_CMD_RSP_DEF(cmd_rsp);
|
||||
bool reset = false;
|
||||
static at_cmd_parse_t pre_parse_rlt;
|
||||
|
||||
s_at_cmd_env.cmd_src = cmd_src;
|
||||
if (pre_parse_rlt.cmd_id == AT_CMD_CONN_INIT)
|
||||
{
|
||||
s_at_cmd_env.cmd_state = AT_CMD_IN_READY_PARSE;
|
||||
reset = true;
|
||||
}
|
||||
|
||||
// Check parse cmd is allowed or not
|
||||
if (AT_CMD_IN_READY_PARSE != s_at_cmd_env.cmd_state)
|
||||
{
|
||||
cmd_rsp.error_code = AT_CMD_ERR_PARSE_NOT_ALLOWED;
|
||||
at_cmd_execute_cplt(&cmd_rsp);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_at_cmd_env.cmd_state = AT_CMD_IN_PARSING;
|
||||
}
|
||||
|
||||
// Check cmd input is integrity or not
|
||||
if (!at_cmd_integrity_check(p_data, length, &s_parse_rlt))
|
||||
{
|
||||
cmd_rsp.error_code = AT_CMD_ERR_INVALID_INPUT;
|
||||
at_cmd_execute_cplt(&cmd_rsp);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get cmd parameters
|
||||
at_cmd_args_get(&s_parse_rlt);
|
||||
|
||||
// Get cmd Id
|
||||
at_cmd_id_get(&s_parse_rlt);
|
||||
|
||||
if (reset && s_parse_rlt.cmd_id == AT_CMD_CONN_CANCEL)
|
||||
{
|
||||
cmd_rsp.error_code = AT_CMD_ERR_NO_ERROR;
|
||||
cmd_rsp.length = at_cmd_printf_bush(cmd_rsp.data, "start cancel connect...");
|
||||
at_cmd_execute_cplt(&cmd_rsp);
|
||||
}
|
||||
|
||||
// Check cmd id is valid or not
|
||||
if (AT_CMD_INVALID == s_parse_rlt.cmd_id)
|
||||
{
|
||||
cmd_rsp.error_code = AT_CMD_ERR_UNSUPPORTED_CMD;
|
||||
at_cmd_execute_cplt(&cmd_rsp);
|
||||
return;
|
||||
}
|
||||
|
||||
s_at_cmd_env.cmd_state = AT_CMD_IN_WAITE_EXECUTE;
|
||||
pre_parse_rlt = s_parse_rlt;
|
||||
}
|
||||
|
||||
void at_cmd_execute_timing_process(void)
|
||||
{
|
||||
AT_CMD_RSP_DEF(cmd_rsp);
|
||||
|
||||
if (AT_CMD_IN_READY_PARSE != s_at_cmd_env.cmd_state)
|
||||
{
|
||||
s_at_cmd_env.cmd_state = AT_CMD_IN_READY_PARSE;
|
||||
|
||||
cmd_rsp.error_code = AT_CMD_ERR_TIMEOUT;
|
||||
at_cmd_execute_cplt(&cmd_rsp);
|
||||
}
|
||||
}
|
||||
|
||||
void at_cmd_execute_cplt(at_cmd_rsp_t *p_cmd_rsp)
|
||||
{
|
||||
uint8_t length = 0;
|
||||
|
||||
if (AT_CMD_ERR_NO_ERROR != p_cmd_rsp->error_code)
|
||||
{
|
||||
switch(p_cmd_rsp->error_code)
|
||||
{
|
||||
case AT_CMD_ERR_INVALID_INPUT:
|
||||
length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: Invalid input.");
|
||||
break;
|
||||
case AT_CMD_ERR_UNSUPPORTED_CMD:
|
||||
length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: Unsupported AT CMD.");
|
||||
break;
|
||||
case AT_CMD_ERR_PARSE_NOT_ALLOWED:
|
||||
length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: No allowed parse state.");
|
||||
break;
|
||||
case AT_CMD_ERR_CMD_REQ_ALLOWED:
|
||||
length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: Command request is not allowed.");
|
||||
break;
|
||||
case AT_CMD_ERR_NO_CMD_HANDLER:
|
||||
length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: No AT CMD handler.");
|
||||
break;
|
||||
case AT_CMD_ERR_INVALID_PARAM:
|
||||
length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: Invalid parameters.");
|
||||
break;
|
||||
case AT_CMD_ERR_HAL_ERROR:
|
||||
length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: Hal error.");
|
||||
break;
|
||||
case AT_CMD_ERR_TIMEOUT:
|
||||
length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: AT CMD execute timeout.");
|
||||
break;
|
||||
case AT_CMD_ERR_OTHER_ERROR:
|
||||
length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: Other error code.");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(at_cmd_rsp_buff, p_cmd_rsp->data, p_cmd_rsp->length);
|
||||
length = p_cmd_rsp->length;
|
||||
}
|
||||
|
||||
at_cmd_rsp_buff[length] = 0x0d;
|
||||
at_cmd_rsp_buff[length + 1] = 0x0a;
|
||||
|
||||
if (s_at_cmd_env.cmd_cplt_cb)
|
||||
{
|
||||
if (AT_CMD_SRC_UART == s_at_cmd_env.cmd_src)
|
||||
{
|
||||
s_at_cmd_env.cmd_cplt_cb(AT_CMD_RSP_DEST_UART, at_cmd_rsp_buff, length + 2);
|
||||
}
|
||||
else if (AT_CMD_SRC_BLE == s_at_cmd_env.cmd_src)
|
||||
{
|
||||
s_at_cmd_env.cmd_cplt_cb(AT_CMD_RSP_DEST_BLE, at_cmd_rsp_buff, length + 2);
|
||||
}
|
||||
}
|
||||
|
||||
s_at_cmd_env.cmd_state = AT_CMD_IN_READY_PARSE;
|
||||
if (AT_CMD_ERR_TIMEOUT == p_cmd_rsp->error_code &&
|
||||
s_at_cmd_env.p_cmd_attr[s_parse_rlt.cmd_idx].cmd_timeout_str)
|
||||
{
|
||||
char *cmd_timeout_str = s_at_cmd_env.p_cmd_attr[s_parse_rlt.cmd_idx].cmd_timeout_str;
|
||||
uint16_t length = strlen(cmd_timeout_str);
|
||||
at_cmd_parse(s_at_cmd_env.cmd_src, (const uint8_t *)cmd_timeout_str, length);
|
||||
}
|
||||
}
|
||||
|
||||
void at_cmd_schedule(void)
|
||||
{
|
||||
if (AT_CMD_IN_WAITE_EXECUTE == s_at_cmd_env.cmd_state)
|
||||
{
|
||||
s_at_cmd_env.cmd_state = AT_CMD_IN_EXECUTING;
|
||||
|
||||
if (s_at_cmd_env.p_cmd_attr[s_parse_rlt.cmd_idx].cmd_handler)
|
||||
{
|
||||
if (s_at_cmd_env.cmd_time_cb)
|
||||
{
|
||||
s_at_cmd_env.cmd_time_cb();
|
||||
}
|
||||
|
||||
s_at_cmd_env.p_cmd_attr[s_parse_rlt.cmd_idx].cmd_handler(&s_parse_rlt);
|
||||
}
|
||||
else
|
||||
{
|
||||
AT_CMD_RSP_DEF(cmd_rsp);
|
||||
cmd_rsp.error_code = AT_CMD_ERR_NO_CMD_HANDLER;
|
||||
at_cmd_execute_cplt(&cmd_rsp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file AT_CMD.h
|
||||
*
|
||||
* @brief AT Command API
|
||||
*
|
||||
*****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __AT_CMD_H_
|
||||
#define __AT_CMD_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup AT_CMD_MACRO Defines
|
||||
* @{
|
||||
*/
|
||||
#define AT_CMD_BUFFER_SIZE_MAX 256 /**< Maximum size of AT CMD buffer. */
|
||||
#define AT_CMD_ARG_COUNT_MAX 28 /**< Maximum number of arguments input. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup AT_CMD_ENUM Enumerations
|
||||
* @{
|
||||
*/
|
||||
/**@brief AT CMD state. */
|
||||
typedef enum
|
||||
{
|
||||
AT_CMD_IN_READY_PARSE = 0x01, /**< Ready for AT CMD parse state. */
|
||||
AT_CMD_IN_PARSING, /**< In parsing AT CMD state. */
|
||||
AT_CMD_IN_WAITE_EXECUTE, /**< Waite for executing state. */
|
||||
AT_CMD_IN_EXECUTING, /**< In executing state. */
|
||||
} at_cmd_state_t;
|
||||
|
||||
/**@brief AT CMD source type. */
|
||||
typedef enum
|
||||
{
|
||||
AT_CMD_SRC_INVALID, /**< Invalid AT CMD source. */
|
||||
AT_CMD_SRC_UART, /**< AT CMD source: Uart. */
|
||||
AT_CMD_SRC_BLE, /**< AT CMD source: BLE. */
|
||||
} at_cmd_src_t;
|
||||
|
||||
/**@brief AT CMD response destination type. */
|
||||
typedef enum
|
||||
{
|
||||
AT_CMD_RSP_DEST_INVALID, /**< Invalid AT CMD response destination. */
|
||||
AT_CMD_RSP_DEST_UART, /**< AT CMD response destination: Uart. */
|
||||
AT_CMD_RSP_DEST_BLE, /**< AT CMD response destination: BLE.*/
|
||||
} at_cmd_rsp_dest_t;
|
||||
|
||||
/**@brief AT CMD ID type. */
|
||||
typedef enum
|
||||
{
|
||||
AT_CMD_INVALID, /**< Invalid AT CMD type. */
|
||||
AT_CMD_TEST, /**< Test module AT CMD. */
|
||||
AT_CMD_VERSION_GET, /**< Module version get AT CMD. */
|
||||
AT_CMD_RESET, /**< System reset. */
|
||||
AT_CMD_BAUD_SET, /**< Uart baud rate set AT CMD. */
|
||||
AT_CMD_ADDR_GET, /**< Board address get AT CMD. */
|
||||
AT_CMD_GAP_ROLE_GET, /**< GAP role get AT CMD. */
|
||||
AT_CMD_GAP_ROLE_SET, /**< GAP role set AT CMD. */
|
||||
AT_CMD_GAP_NAME_GET, /**< GAP name get AT CMD. */
|
||||
AT_CMD_GAP_NAME_SET, /**< GAP name set AT CMD. */
|
||||
AT_CMD_ADV_PARAM_SET, /**< Advertising parameters set AT CMD. */
|
||||
AT_CMD_ADV_DATA_SET, /**< Advertising data set AT CMD. */
|
||||
AT_CMD_RSP_DATA_SET, /**< Scan response data set AT CMD. */
|
||||
AT_CMD_ADV_START, /**< Start advertising AT CMD. */
|
||||
AT_CMD_ADV_STOP, /**< Stop advertising AT CMD. */
|
||||
AT_CMD_SCAN_PARAM_SET, /**< Scan parameters set AT CMD. */
|
||||
AT_CMD_SCAN_START, /**< Start scan AT CMD. */
|
||||
AT_CMD_SCAN_STOP, /**< Stop scan AT CMD. */
|
||||
AT_CMD_CONN_PARAM_SET, /**< Connect parameters set AT CMD. */
|
||||
AT_CMD_CONN_INIT, /**< Initiate connection AT CMD. */
|
||||
AT_CMD_CONN_CANCEL, /**< Cancel connection AT CMD. */
|
||||
AT_CMD_DISCONN, /**< Disconnect AT CMD. */
|
||||
AT_CMD_MTU_EXCHANGE, /**< Exchange MTU AT CMD. */
|
||||
AT_CMD_SRVC_DISC, /**< Discovery service AT CMD. */
|
||||
AT_CMD_CONN_PARAM_UPDATE, /**< Connect parameters update AT CMD. */
|
||||
AT_CMD_ATTR_READ, /**< Read attr AT CMD. */
|
||||
AT_CMD_ATTR_WRITE, /**< Write attr AT CMD. */
|
||||
AT_CMD_NB /**< Number of supported AT CMD. */
|
||||
} at_cmd_id_t;
|
||||
|
||||
/**@brief AT CMD error code. */
|
||||
typedef enum
|
||||
{
|
||||
AT_CMD_ERR_NO_ERROR, /**< No error. */
|
||||
AT_CMD_ERR_INVALID_INPUT, /**< Invalid input. */
|
||||
AT_CMD_ERR_UNSUPPORTED_CMD, /**< Unsupported AT CMD. */
|
||||
AT_CMD_ERR_PARSE_NOT_ALLOWED, /**< No allowed parse state. */
|
||||
AT_CMD_ERR_CMD_REQ_ALLOWED, /**< Command request is not allowed. */
|
||||
AT_CMD_ERR_NO_CMD_HANDLER, /**< No AT CMD handler. */
|
||||
AT_CMD_ERR_INVALID_PARAM, /**< Invalid parameters. */
|
||||
AT_CMD_ERR_HAL_ERROR, /**< Hal error. */
|
||||
AT_CMD_ERR_TIMEOUT, /**< AT CMD execute timeout. */
|
||||
|
||||
AT_CMD_ERR_OTHER_ERROR, /**< Other error code. */
|
||||
} at_cmd_error_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup AT_CMD_STRUCT Structures
|
||||
* @{
|
||||
*/
|
||||
/**@brief AT CMD parse result. */
|
||||
typedef struct
|
||||
{
|
||||
at_cmd_id_t cmd_id; /**< AT CMD ID type. */
|
||||
uint8_t cmd_idx; /**< AT CMD index in its table. */
|
||||
uint8_t cmd_tag_idx; /**< AT CMD tag index. */
|
||||
uint8_t cmd_tag_length; /**< Length of AT CMD tag. */
|
||||
uint8_t arg_count; /**< Count of arguments. */
|
||||
uint8_t arg_idx[AT_CMD_ARG_COUNT_MAX]; /**< Index of arguments. */
|
||||
uint8_t arg_length[AT_CMD_ARG_COUNT_MAX]; /**< Length of arguments. */
|
||||
uint8_t *p_buff; /**< Pointer to AT CMD buffer. */
|
||||
uint16_t buff_length; /**< BUffer valid length. */
|
||||
} at_cmd_parse_t;
|
||||
|
||||
/**@brief AT CMD response variables. */
|
||||
typedef struct
|
||||
{
|
||||
at_cmd_error_t error_code; /**< Error code. */
|
||||
uint8_t data[AT_CMD_BUFFER_SIZE_MAX]; /**< Response data. */
|
||||
uint16_t length; /**< Length of response data. */
|
||||
} at_cmd_rsp_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup AT_CMD_TYPEDEF Typedefs
|
||||
* @{
|
||||
*/
|
||||
/**@brief AT CMD handler type. */
|
||||
typedef void (*at_cmd_handler_t)(at_cmd_parse_t *p_cmd_parse);
|
||||
|
||||
/**@brief AT CMD execute timing callback type. */
|
||||
typedef void (*at_cmd_time_callback_t)(void);
|
||||
|
||||
/**@brief AT CMD execute complete callback type. */
|
||||
typedef void (*at_cmd_cplt_callback_t)(at_cmd_rsp_dest_t rsp_dest, const uint8_t *p_data, uint8_t length);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup AT_CMD_STRUCT Structures
|
||||
* @{
|
||||
*/
|
||||
/**@brief AT CMD attribute. */
|
||||
typedef struct
|
||||
{
|
||||
at_cmd_id_t cmd_id; /**< AT CMD ID type. */
|
||||
char *cmd_tag_str; /**< String of AT CMD tag. */
|
||||
uint8_t cmd_tag_length; /**< Length of AT CMD tag. */
|
||||
at_cmd_handler_t cmd_handler; /**< AT CMD handler. */
|
||||
char *cmd_timeout_str; /**< String of timeout AT CMD. */
|
||||
} at_cmd_attr_t;
|
||||
|
||||
/**@brief AT CMD initialization variables. */
|
||||
typedef struct
|
||||
{
|
||||
at_cmd_attr_t *p_cmd_attr; /**< Pointer to AT CMD attribute table. */
|
||||
uint8_t cmd_num; /**< Number of AT CMD register. */
|
||||
at_cmd_time_callback_t cmd_time_cb; /**< AT CMD timing callback. */
|
||||
at_cmd_cplt_callback_t cmd_cplt_cb; /**< AT CMD execute complete callback. */
|
||||
} at_cmd_init_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup AT_CMD_FUNCTION Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Initialize AT CMD module.
|
||||
*
|
||||
* @param[in] p_cmd_init: Pointer to p_cmd_init.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void at_cmd_init(at_cmd_init_t *p_cmd_init);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Parse user input data.
|
||||
*
|
||||
* @param[in] cmd_src: Source of input.
|
||||
* @param[in] p_data: Pointer to input data.
|
||||
* @param[in] length: Length of input data.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void at_cmd_parse(at_cmd_src_t cmd_src, const uint8_t *p_data, uint16_t length);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Process AT CMD execute timing check.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void at_cmd_execute_timing_process(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief AT CMD execute complete.
|
||||
*
|
||||
* @param[in] p_cmd_rsp: Pointer to cmd response.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void at_cmd_execute_cplt(at_cmd_rsp_t *p_cmd_rsp);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief AT CMD schedule, called in main().
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void at_cmd_schedule(void);
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file at_cmd_utils.c
|
||||
*
|
||||
* @brief AT Command Utilities implementation.
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
#include "at_cmd_utils.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
uint8_t at_cmd_printf_bush(uint8_t *p_buff, const char *format, ...)
|
||||
{
|
||||
char str_temp[AT_CMD_BUFFER_SIZE_MAX];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
vsprintf(str_temp, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
memcpy(p_buff, (uint8_t *)str_temp, strlen(str_temp));
|
||||
|
||||
return (strlen(str_temp));
|
||||
}
|
||||
|
||||
bool at_cmd_decimal_num_check(uint8_t *p_data, uint16_t length, uint32_t *p_num)
|
||||
{
|
||||
if (0 == length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*p_num = 0;
|
||||
|
||||
for (uint8_t i = 0; i < length; i++)
|
||||
{
|
||||
if ('0' > p_data[i] || '9' < p_data[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*p_num = (*p_num * 10) + (p_data[i] - '0');
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool at_cmd_hex_num_check(uint8_t *p_data, uint16_t length, uint32_t *p_num)
|
||||
{
|
||||
if (2 >= length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*p_num = 0;
|
||||
if ('0' != p_data[0]||('X' != p_data[1]&&'x' != p_data[1]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (uint8_t i = 2; i < length; i++)
|
||||
{
|
||||
if ('0' <= p_data[i] && '9' >= p_data[i])
|
||||
{
|
||||
*p_num = (*p_num * 16) + (p_data[i] - '0');
|
||||
}
|
||||
else if ('a' <= p_data[i] && 'f' >= p_data[i])
|
||||
{
|
||||
*p_num = (*p_num * 16) + (p_data[i] - 'a' + 10);
|
||||
}
|
||||
else if ('A' <= p_data[i] && 'F' >= p_data[i])
|
||||
{
|
||||
*p_num = (*p_num * 16) + (p_data[i] - 'A' + 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
at_cmd_error_t at_cmd_hal_err_convert(hal_status_t error_code)
|
||||
{
|
||||
switch (error_code)
|
||||
{
|
||||
case HAL_OK:
|
||||
return AT_CMD_ERR_NO_ERROR;
|
||||
|
||||
case HAL_ERROR:
|
||||
case HAL_BUSY:
|
||||
case HAL_TIMEOUT:
|
||||
return AT_CMD_ERR_HAL_ERROR;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return AT_CMD_ERR_NO_ERROR;
|
||||
}
|
||||
|
||||
at_cmd_error_t at_cmd_ble_err_convert(sdk_err_t error_code)
|
||||
{
|
||||
switch (error_code)
|
||||
{
|
||||
case BLE_SUCCESS:
|
||||
return AT_CMD_ERR_NO_ERROR;
|
||||
|
||||
case SDK_ERR_INVALID_PARAM:
|
||||
case BLE_GAP_ERR_INVALID_PARAM:
|
||||
return AT_CMD_ERR_INVALID_PARAM;
|
||||
|
||||
default:
|
||||
return AT_CMD_ERR_OTHER_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file AT_CMD_UTILS.h
|
||||
*
|
||||
* @brief AT Command Utilities API
|
||||
*
|
||||
*****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __AT_CMD_UTILS_H__
|
||||
#define __AT_CMD_UTILS_H__
|
||||
|
||||
#include "at_cmd.h"
|
||||
#include "grx_hal.h"
|
||||
#include "grx_sys.h"
|
||||
|
||||
/**
|
||||
* @defgroup AT_CMD_UTILS_MACRO Defines
|
||||
* @{
|
||||
*/
|
||||
#define ERROR_CHECK(error_code) do \
|
||||
{ \
|
||||
if (0 != error_code) \
|
||||
{ \
|
||||
return error_code; \
|
||||
} \
|
||||
} while(0) /**< Error check. */
|
||||
|
||||
#define AT_CMD_RSP_DEF(at_cmd_rsp) at_cmd_rsp_t at_cmd_rsp = \
|
||||
{ \
|
||||
.error_code = AT_CMD_ERR_NO_ERROR, \
|
||||
.data = {0}, \
|
||||
.length = 0, \
|
||||
} /**< Define AT CMD response variable. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup CTS_C_FUNCTION Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Prinf string and push to buffer.
|
||||
*
|
||||
* @param[in] p_buff: Pointer to buffer.
|
||||
*
|
||||
* @result Length of data push to buffer.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
uint8_t at_cmd_printf_bush(uint8_t *p_buff, const char *format, ...);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Check decimal number is valid and calculate.
|
||||
*
|
||||
* @param[in] p_data: Pointer to data.
|
||||
* @param[in] length: Length of dta.
|
||||
* @param[out] p_num: Result of calculate.
|
||||
|
||||
* @result Result of check.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
bool at_cmd_decimal_num_check(uint8_t *p_data, uint16_t length, uint32_t *p_num);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Check hexadecimal number is valid and calculate.
|
||||
*
|
||||
* @param[in] p_data: Pointer to data.
|
||||
* @param[in] length: Length of dta.
|
||||
* @param[out] p_num: Result of calculate.
|
||||
*
|
||||
* @result Result of check.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
bool at_cmd_hex_num_check(uint8_t *p_data, uint16_t length, uint32_t *p_num);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Convert hal error code to AT CMD error code.
|
||||
*
|
||||
* @param[in] error_code: HAL error code.
|
||||
*
|
||||
* @result Result of convert.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
at_cmd_error_t at_cmd_hal_err_convert(hal_status_t error_code);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Convert ble error code to AT CMD error code.
|
||||
*
|
||||
* @param[in] error_code: BLE error code.
|
||||
*
|
||||
* @result Result of convert.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
at_cmd_error_t at_cmd_ble_err_convert(sdk_err_t error_code);
|
||||
/** @} */
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
kernel_module("ble_advertising") {
|
||||
sources = [ "ble_advertising.c" ]
|
||||
}
|
||||
+512
@@ -0,0 +1,512 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file ble_advertising.c
|
||||
*
|
||||
* @brief BLE Advertising Module API
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "ble_module_config.h"
|
||||
#if BLE_ADVERTISING_ENABLE
|
||||
#include "ble_advertising.h"
|
||||
|
||||
/*
|
||||
* DEFINES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#define BLE_ADV_HIGH_DUTY_DIR_DURATION 128
|
||||
#define BLE_ADV_INTERVAL_MIN 32
|
||||
#define BLE_ADV_DURATION_MAX 18000
|
||||
|
||||
/*
|
||||
* STRUCTURES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
/**@brief BLE Advertising Module environment variable. */
|
||||
struct ble_adv_env_t
|
||||
{
|
||||
bool initialized;
|
||||
bool adv_act_exist;
|
||||
ble_adv_mode_t cur_adv_mode;
|
||||
ble_adv_mode_cfg_t adv_mode_cfg;
|
||||
ble_adv_evt_handler_t evt_handler;
|
||||
ble_adv_err_handler_t err_handler;
|
||||
ble_gap_ext_adv_param_t adv_param;
|
||||
ble_gap_adv_time_param_t adv_time_param;
|
||||
bool peer_addr_exist;
|
||||
};
|
||||
|
||||
/*
|
||||
* LOCAL VARIABLE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static struct ble_adv_env_t adv_env;
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static ble_adv_mode_t adv_mode_next_get(ble_adv_mode_t adv_mode)
|
||||
{
|
||||
return (ble_adv_mode_t)((adv_mode + 1) % (BLE_ADV_MODE_SLOW + 2));
|
||||
}
|
||||
|
||||
static ble_adv_mode_t adv_mode_next_avail_get(ble_adv_mode_cfg_t *p_adv_mode_cfg, ble_adv_mode_t adv_mode)
|
||||
{
|
||||
switch (adv_mode)
|
||||
{
|
||||
case BLE_ADV_MODE_DIRECTED_HIGH_DUTY:
|
||||
if ((p_adv_mode_cfg->adv_directed_high_duty_enabled) && (!p_adv_mode_cfg->adv_extended_enabled) &&
|
||||
adv_env.peer_addr_exist)
|
||||
{
|
||||
return BLE_ADV_MODE_DIRECTED_HIGH_DUTY;
|
||||
}
|
||||
|
||||
case BLE_ADV_MODE_DIRECTED_LOW_DUTY:
|
||||
if ((p_adv_mode_cfg->adv_directed_low_duty_enabled && adv_env.peer_addr_exist))
|
||||
{
|
||||
return BLE_ADV_MODE_DIRECTED_LOW_DUTY;
|
||||
}
|
||||
|
||||
case BLE_ADV_MODE_FAST:
|
||||
if (p_adv_mode_cfg->adv_fast_enabled)
|
||||
{
|
||||
return BLE_ADV_MODE_FAST;
|
||||
}
|
||||
|
||||
case BLE_ADV_MODE_SLOW:
|
||||
if (p_adv_mode_cfg->adv_slow_enabled)
|
||||
{
|
||||
return BLE_ADV_MODE_SLOW;
|
||||
}
|
||||
|
||||
default:
|
||||
return BLE_ADV_MODE_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
static sdk_err_t directed_high_duty_adv_param_set(struct ble_adv_env_t *p_adv_env)
|
||||
{
|
||||
p_adv_env->adv_param.type = BLE_GAP_ADV_TYPE_LEGACY;
|
||||
p_adv_env->adv_param.prop = BLE_GAP_ADV_PROP_CONNECTABLE_BIT |
|
||||
BLE_GAP_ADV_PROP_DIRECTED_BIT |
|
||||
BLE_GAP_ADV_PROP_HDC_BIT;
|
||||
p_adv_env->adv_param.disc_mode = BLE_GAP_DISC_MODE_NON_DISCOVERABLE;
|
||||
|
||||
p_adv_env->adv_time_param.max_adv_evt = 0;
|
||||
|
||||
p_adv_env->adv_time_param.duration = BLE_ADV_HIGH_DUTY_DIR_DURATION;
|
||||
|
||||
return ble_gap_ext_adv_param_set(0, BLE_GAP_OWN_ADDR_GEN_RSLV, &p_adv_env->adv_param);
|
||||
}
|
||||
|
||||
static sdk_err_t directed_low_duty_adv_param_set(struct ble_adv_env_t *p_adv_env)
|
||||
{
|
||||
if (p_adv_env->adv_mode_cfg.adv_extended_enabled)
|
||||
{
|
||||
p_adv_env->adv_param.type = BLE_GAP_ADV_TYPE_EXTENDED;
|
||||
p_adv_env->adv_param.prop = BLE_GAP_ADV_PROP_DIRECTED_BIT |
|
||||
BLE_GAP_ADV_PROP_CONNECTABLE_BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_adv_env->adv_param.type = BLE_GAP_ADV_TYPE_LEGACY;
|
||||
p_adv_env->adv_param.prop = BLE_GAP_ADV_PROP_DIRECTED_BIT |
|
||||
BLE_GAP_ADV_PROP_CONNECTABLE_BIT;
|
||||
}
|
||||
p_adv_env->adv_param.prim_cfg.adv_intv_min = p_adv_env->adv_mode_cfg.adv_directed_low_duty_interval;
|
||||
p_adv_env->adv_param.prim_cfg.adv_intv_max = p_adv_env->adv_mode_cfg.adv_directed_low_duty_interval;
|
||||
p_adv_env->adv_param.disc_mode = BLE_GAP_DISC_MODE_NON_DISCOVERABLE;
|
||||
|
||||
p_adv_env->adv_time_param.max_adv_evt = 0;
|
||||
p_adv_env->adv_time_param.duration = p_adv_env->adv_mode_cfg.adv_directed_low_duty_timeout;
|
||||
return ble_gap_ext_adv_param_set(0, BLE_GAP_OWN_ADDR_GEN_RSLV, &p_adv_env->adv_param);
|
||||
}
|
||||
|
||||
static sdk_err_t fast_adv_param_set(struct ble_adv_env_t *p_adv_env)
|
||||
{
|
||||
if (p_adv_env->adv_mode_cfg.adv_extended_enabled)
|
||||
{
|
||||
p_adv_env->adv_param.type = BLE_GAP_ADV_TYPE_EXTENDED;
|
||||
p_adv_env->adv_param.prop = BLE_GAP_ADV_PROP_CONNECTABLE_BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_adv_env->adv_param.type = BLE_GAP_ADV_TYPE_LEGACY;
|
||||
p_adv_env->adv_param.prop = BLE_GAP_ADV_PROP_SCANNABLE_BIT |
|
||||
BLE_GAP_ADV_PROP_CONNECTABLE_BIT;
|
||||
}
|
||||
p_adv_env->adv_param.prim_cfg.adv_intv_min = p_adv_env->adv_mode_cfg.adv_fast_interval;
|
||||
p_adv_env->adv_param.prim_cfg.adv_intv_max = p_adv_env->adv_mode_cfg.adv_fast_interval;
|
||||
p_adv_env->adv_param.disc_mode = (p_adv_env->adv_param.filter_pol == BLE_GAP_ADV_ALLOW_SCAN_ANY_CON_ANY)?
|
||||
BLE_GAP_DISC_MODE_GEN_DISCOVERABLE : BLE_GAP_DISC_MODE_NON_DISCOVERABLE;
|
||||
|
||||
p_adv_env->adv_time_param.max_adv_evt = 0;
|
||||
p_adv_env->adv_time_param.duration = p_adv_env->adv_mode_cfg.adv_fast_timeout;
|
||||
|
||||
return ble_gap_ext_adv_param_set(0, BLE_GAP_OWN_ADDR_STATIC, &p_adv_env->adv_param);
|
||||
}
|
||||
|
||||
static sdk_err_t slow_adv_param_set(struct ble_adv_env_t *p_adv_env)
|
||||
{
|
||||
if (p_adv_env->adv_mode_cfg.adv_extended_enabled)
|
||||
{
|
||||
p_adv_env->adv_param.type = BLE_GAP_ADV_TYPE_EXTENDED;
|
||||
p_adv_env->adv_param.prop = BLE_GAP_ADV_PROP_CONNECTABLE_BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_adv_env->adv_param.type = BLE_GAP_ADV_TYPE_LEGACY;
|
||||
p_adv_env->adv_param.prop = BLE_GAP_ADV_PROP_SCANNABLE_BIT |
|
||||
BLE_GAP_ADV_PROP_CONNECTABLE_BIT;
|
||||
}
|
||||
p_adv_env->adv_param.prim_cfg.adv_intv_min = p_adv_env->adv_mode_cfg.adv_slow_interval;
|
||||
p_adv_env->adv_param.prim_cfg.adv_intv_max = p_adv_env->adv_mode_cfg.adv_slow_interval;
|
||||
p_adv_env->adv_param.disc_mode = (p_adv_env->adv_param.filter_pol == BLE_GAP_ADV_ALLOW_SCAN_ANY_CON_ANY)?
|
||||
BLE_GAP_DISC_MODE_GEN_DISCOVERABLE : BLE_GAP_DISC_MODE_NON_DISCOVERABLE;
|
||||
|
||||
p_adv_env->adv_time_param.max_adv_evt = 0;
|
||||
p_adv_env->adv_time_param.duration = p_adv_env->adv_mode_cfg.adv_slow_timeout;
|
||||
|
||||
return ble_gap_ext_adv_param_set(0, BLE_GAP_OWN_ADDR_STATIC, &p_adv_env->adv_param);
|
||||
}
|
||||
|
||||
static void ble_adv_started(void)
|
||||
{
|
||||
ble_adv_evt_type_t evt = BLE_ADV_EVT_INVALID;
|
||||
|
||||
switch(adv_env.cur_adv_mode)
|
||||
{
|
||||
case BLE_ADV_MODE_DIRECTED_HIGH_DUTY:
|
||||
evt = BLE_ADV_EVT_DIRECTED_HIGH_DUTY;
|
||||
break;
|
||||
|
||||
case BLE_ADV_MODE_DIRECTED_LOW_DUTY:
|
||||
evt = BLE_ADV_EVT_DIRECTED_LOW_DUTY;
|
||||
break;
|
||||
|
||||
case BLE_ADV_MODE_FAST:
|
||||
evt = BLE_ADV_EVT_FAST;
|
||||
break;
|
||||
|
||||
case BLE_ADV_MODE_SLOW:
|
||||
evt = BLE_ADV_EVT_SLOW;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
adv_env.adv_act_exist = true;
|
||||
|
||||
if (adv_env.evt_handler && evt)
|
||||
{
|
||||
adv_env.evt_handler(evt);
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_advertising_err_on_ble_capture(uint8_t err_code)
|
||||
{
|
||||
if (adv_env.err_handler && err_code)
|
||||
{
|
||||
adv_env.err_handler(err_code);
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_adv_stopped(uint8_t stop_reason)
|
||||
{
|
||||
sdk_err_t err_code;
|
||||
|
||||
adv_env.adv_act_exist = false;
|
||||
|
||||
if (BLE_GAP_STOPPED_REASON_TIMEOUT == stop_reason)
|
||||
{
|
||||
err_code = ble_advertising_start(adv_mode_next_get(adv_env.cur_adv_mode));
|
||||
ble_advertising_err_on_ble_capture(err_code);
|
||||
}
|
||||
else if (BLE_GAP_STOPPED_REASON_CONN_EST == stop_reason)
|
||||
{
|
||||
if (adv_env.adv_mode_cfg.multi_link_enabled && !adv_env.adv_act_exist)
|
||||
{
|
||||
ble_advertising_start(BLE_ADV_MODE_DIRECTED_HIGH_DUTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_adv_disconnected(void)
|
||||
{
|
||||
if (adv_env.adv_mode_cfg.adv_on_disconnect_enabled && !adv_env.adv_act_exist)
|
||||
{
|
||||
ble_advertising_start(BLE_ADV_MODE_DIRECTED_HIGH_DUTY);
|
||||
}
|
||||
}
|
||||
|
||||
static sdk_err_t adv_init_param_check(ble_adv_init_t *p_adv_init)
|
||||
{
|
||||
if (NULL == p_adv_init)
|
||||
{
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
|
||||
ble_adv_mode_cfg_t *p_cfg = &p_adv_init->adv_mode_cfg;
|
||||
|
||||
if (p_cfg->adv_directed_low_duty_enabled &&
|
||||
(p_cfg->adv_directed_low_duty_interval < BLE_ADV_INTERVAL_MIN || p_cfg->adv_directed_low_duty_timeout > BLE_ADV_DURATION_MAX))
|
||||
{
|
||||
return SDK_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (p_cfg->adv_fast_enabled &&
|
||||
(p_cfg->adv_fast_interval < BLE_ADV_INTERVAL_MIN || p_cfg->adv_fast_interval > BLE_ADV_DURATION_MAX))
|
||||
{
|
||||
return SDK_ERR_INVALID_PARAM;
|
||||
}
|
||||
if (p_cfg->adv_slow_enabled &&
|
||||
(p_cfg->adv_slow_interval < BLE_ADV_INTERVAL_MIN || p_cfg->adv_slow_interval > BLE_ADV_DURATION_MAX))
|
||||
{
|
||||
return SDK_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
*******************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_advertising_init(ble_adv_init_t *p_adv_init)
|
||||
{
|
||||
sdk_err_t error_code;
|
||||
|
||||
if (adv_env.initialized)
|
||||
{
|
||||
return SDK_ERR_DISALLOWED;
|
||||
}
|
||||
|
||||
error_code = adv_init_param_check(p_adv_init);
|
||||
RET_VERIFY_SUCCESS(error_code);
|
||||
|
||||
adv_env.cur_adv_mode = BLE_ADV_MODE_IDLE;
|
||||
adv_env.evt_handler = p_adv_init->evt_handler;
|
||||
adv_env.err_handler = p_adv_init->err_handler;
|
||||
|
||||
memcpy(&adv_env.adv_mode_cfg, &p_adv_init->adv_mode_cfg, sizeof(ble_adv_mode_cfg_t));
|
||||
|
||||
error_code = ble_gap_adv_data_set(0,
|
||||
BLE_GAP_ADV_DATA_TYPE_DATA,
|
||||
p_adv_init->adv_data.p_data,
|
||||
p_adv_init->adv_data.length);
|
||||
|
||||
if (p_adv_init->srp_data.p_data && p_adv_init->srp_data.length && !p_adv_init->adv_mode_cfg.adv_extended_enabled)
|
||||
{
|
||||
error_code = ble_gap_adv_data_set(0,
|
||||
BLE_GAP_ADV_DATA_TYPE_SCAN_RSP,
|
||||
p_adv_init->srp_data.p_data,
|
||||
p_adv_init->srp_data.length);
|
||||
RET_VERIFY_SUCCESS(error_code);
|
||||
}
|
||||
|
||||
RET_VERIFY_SUCCESS(error_code);
|
||||
|
||||
adv_env.initialized = true;
|
||||
|
||||
return error_code;
|
||||
}
|
||||
|
||||
sdk_err_t ble_advertising_start(ble_adv_mode_t adv_mode)
|
||||
{
|
||||
sdk_err_t error_code;
|
||||
|
||||
if (!adv_env.initialized)
|
||||
{
|
||||
return SDK_ERR_DISALLOWED;
|
||||
}
|
||||
|
||||
adv_env.cur_adv_mode = adv_mode;
|
||||
|
||||
//Set general parameters
|
||||
adv_env.adv_param.disc_mode = BLE_GAP_DISC_MODE_GEN_DISCOVERABLE;
|
||||
adv_env.adv_param.max_tx_pwr = 0;
|
||||
adv_env.adv_param.prim_cfg.chnl_map = BLE_GAP_ADV_CHANNEL_37_38_39;
|
||||
adv_env.adv_param.filter_pol = BLE_GAP_ADV_ALLOW_SCAN_ANY_CON_ANY;
|
||||
// adv_env.adv_param.filter_pol = (adv_env.adv_mode_cfg.ble_adv_whitelist_enabled)?
|
||||
// BLE_GAP_ADV_ALLOW_SCAN_ANY_CON_WLST : BLE_GAP_ADV_ALLOW_SCAN_ANY_CON_ANY;
|
||||
adv_env.adv_param.prim_cfg.phy = BLE_GAP_PHY_1MBPS_VALUE;
|
||||
|
||||
if (adv_env.adv_mode_cfg.adv_extended_enabled)
|
||||
{
|
||||
if (adv_env.adv_mode_cfg.adv_primary_phy)
|
||||
{
|
||||
adv_env.adv_param.prim_cfg.phy = adv_env.adv_mode_cfg.adv_primary_phy;
|
||||
}
|
||||
|
||||
if (adv_env.adv_mode_cfg.adv_secondary_phy)
|
||||
{
|
||||
adv_env.adv_param.second_cfg.phy = adv_env.adv_mode_cfg.adv_secondary_phy;
|
||||
}
|
||||
else
|
||||
{
|
||||
adv_env.adv_param.second_cfg.phy = (ble_gap_le_phy_value_t)BLE_GAP_PHY_LE_1MBPS;
|
||||
}
|
||||
}
|
||||
|
||||
if (((adv_env.adv_mode_cfg.adv_directed_high_duty_enabled) && (adv_env.cur_adv_mode == BLE_ADV_MODE_DIRECTED_HIGH_DUTY)) || \
|
||||
((adv_env.adv_mode_cfg.adv_directed_low_duty_enabled) && (adv_env.cur_adv_mode == BLE_ADV_MODE_DIRECTED_HIGH_DUTY)) || \
|
||||
((adv_env.adv_mode_cfg.adv_directed_low_duty_enabled) && (adv_env.cur_adv_mode == BLE_ADV_MODE_DIRECTED_LOW_DUTY)))
|
||||
{
|
||||
if (adv_env.evt_handler)
|
||||
{
|
||||
adv_env.evt_handler(BLE_ADV_EVT_DIR_ADDR_REQUEST);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&adv_env.adv_param.peer_addr, 0, sizeof(ble_gap_bdaddr_t));
|
||||
}
|
||||
|
||||
adv_env.cur_adv_mode = adv_mode_next_avail_get(&adv_env.adv_mode_cfg, adv_mode);
|
||||
|
||||
if (adv_env.adv_mode_cfg.adv_extended_enabled)
|
||||
{
|
||||
if (adv_env.adv_mode_cfg.adv_primary_phy)
|
||||
{
|
||||
adv_env.adv_param.prim_cfg.phy = adv_env.adv_mode_cfg.adv_primary_phy;
|
||||
}
|
||||
|
||||
if (adv_env.adv_mode_cfg.adv_secondary_phy)
|
||||
{
|
||||
adv_env.adv_param.second_cfg.phy = adv_env.adv_mode_cfg.adv_secondary_phy;
|
||||
}
|
||||
}
|
||||
|
||||
switch (adv_env.cur_adv_mode)
|
||||
{
|
||||
case BLE_ADV_MODE_DIRECTED_HIGH_DUTY:
|
||||
error_code = directed_high_duty_adv_param_set(&adv_env);
|
||||
RET_VERIFY_SUCCESS(error_code);
|
||||
break;
|
||||
|
||||
case BLE_ADV_MODE_DIRECTED_LOW_DUTY:
|
||||
error_code = directed_low_duty_adv_param_set(&adv_env);
|
||||
RET_VERIFY_SUCCESS(error_code);
|
||||
break;
|
||||
|
||||
case BLE_ADV_MODE_FAST:
|
||||
error_code = fast_adv_param_set(&adv_env);
|
||||
RET_VERIFY_SUCCESS(error_code);
|
||||
break;
|
||||
|
||||
case BLE_ADV_MODE_SLOW:
|
||||
error_code = slow_adv_param_set(&adv_env);
|
||||
RET_VERIFY_SUCCESS(error_code);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ble_gap_adv_start(0, &adv_env.adv_time_param);
|
||||
}
|
||||
|
||||
sdk_err_t ble_advertising_adv_data_update(const uint8_t *p_adv_data, uint16_t adv_data_len, const uint8_t *p_srsp_data, uint16_t srsp_data_len)
|
||||
{
|
||||
sdk_err_t error_code;
|
||||
|
||||
if ((p_adv_data == NULL) && (p_srsp_data == NULL) && (adv_data_len <= 0) && (srsp_data_len <= 0))
|
||||
{
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
|
||||
if (adv_env.initialized == false)
|
||||
{
|
||||
return SDK_ERR_DISALLOWED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p_adv_data && adv_data_len)
|
||||
{
|
||||
error_code = ble_gap_adv_data_set(0, BLE_GAP_ADV_DATA_TYPE_DATA, p_adv_data, adv_data_len);
|
||||
RET_VERIFY_SUCCESS(error_code);
|
||||
}
|
||||
|
||||
if (p_srsp_data && srsp_data_len)
|
||||
{
|
||||
error_code = ble_gap_adv_data_set(0, BLE_GAP_ADV_DATA_TYPE_SCAN_RSP, p_srsp_data, srsp_data_len);
|
||||
RET_VERIFY_SUCCESS(error_code);
|
||||
}
|
||||
}
|
||||
return error_code;
|
||||
}
|
||||
|
||||
sdk_err_t ble_advertising_dir_addr_fill(ble_gap_bdaddr_t *p_peer_addr)
|
||||
{
|
||||
for (uint8_t i = 0; i < BLE_GAP_ADDR_LEN; i++)
|
||||
{
|
||||
if (p_peer_addr->gap_addr.addr[i] != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
return SDK_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
memcpy(&adv_env.adv_param.peer_addr, p_peer_addr, sizeof(ble_gap_bdaddr_t));
|
||||
adv_env.peer_addr_exist = true;
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
void ble_advertising_evt_on_ble_capture(const ble_evt_t *p_evt)
|
||||
{
|
||||
switch (p_evt->evt_id)
|
||||
{
|
||||
case BLE_GAPM_EVT_ADV_START:
|
||||
ble_adv_started();
|
||||
break;
|
||||
|
||||
case BLE_GAPM_EVT_ADV_STOP:
|
||||
ble_adv_stopped(p_evt->evt.gapm_evt.params.adv_stop.reason);
|
||||
break;
|
||||
|
||||
case BLE_GAPC_EVT_DISCONNECTED:
|
||||
ble_adv_disconnected();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file ble_advertising.h
|
||||
*
|
||||
* @brief BLE Advertising Module Header
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __BLE_ADVERTISING_H__
|
||||
#define __BLE_ADVERTISING_H__
|
||||
|
||||
#include "gr_includes.h"
|
||||
|
||||
/**
|
||||
* @defgroup BLE_ADVERTISING_MAROC Defines
|
||||
* @{
|
||||
*/
|
||||
#define RET_VERIFY_SUCCESS(RET_CODE) \
|
||||
do \
|
||||
{ \
|
||||
if (RET_CODE != SDK_SUCCESS) \
|
||||
{ \
|
||||
return RET_CODE; \
|
||||
} \
|
||||
} while(0)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup BLE_ADVERTISING_ENUM Enumerations
|
||||
* @{
|
||||
*/
|
||||
/**@brief Advertising mode type. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_ADV_MODE_IDLE, /**< No advertising activity. */
|
||||
BLE_ADV_MODE_DIRECTED_HIGH_DUTY, /**< High duty directed advertising. */
|
||||
BLE_ADV_MODE_DIRECTED_LOW_DUTY, /**< Low duty directed advertising. */
|
||||
BLE_ADV_MODE_FAST, /**< Fast advertising mode. */
|
||||
BLE_ADV_MODE_SLOW, /**< Slow advertising mode. */
|
||||
} ble_adv_mode_t;
|
||||
|
||||
/**@brief Advertising events type. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_ADV_EVT_INVALID, /**< Invalid advertising event. */
|
||||
BLE_ADV_EVT_DIRECTED_HIGH_DUTY, /**< High duty directed advertising started. */
|
||||
BLE_ADV_EVT_DIRECTED_LOW_DUTY, /**< Low duty directed advertising started. */
|
||||
BLE_ADV_EVT_FAST, /**< Fast advertising started. */
|
||||
BLE_ADV_EVT_SLOW, /**< Slow advertising started. */
|
||||
BLE_ADV_EVT_DIR_ADDR_REQUEST, /**< Request peer address for directed advertising. */
|
||||
} ble_adv_evt_type_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup BLE_ADVERTISING_TYPEDEF Typedefs
|
||||
* @{
|
||||
*/
|
||||
/**@brief BLE advertising event handler type. */
|
||||
typedef void (*ble_adv_evt_handler_t)(ble_adv_evt_type_t evt);
|
||||
|
||||
/**@brief BLE advertising error handler type. */
|
||||
typedef void (*ble_adv_err_handler_t)(uint8_t err_code);
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup BLE_ADVERTISING_STRUCT Structures
|
||||
* @{
|
||||
*/
|
||||
/**@brief Data structure. */
|
||||
typedef struct
|
||||
{
|
||||
const uint8_t *p_data; /**< Pointer to the data. */
|
||||
uint16_t length; /**< Length of the data. */
|
||||
} ble_data_t;
|
||||
|
||||
/**@brief Options for the different advertisement modes.*/
|
||||
typedef struct
|
||||
{
|
||||
bool multi_link_enabled; /**< Enable or disable multi link. */
|
||||
bool adv_on_disconnect_enabled; /**< Enable or disable auto advertising after disconnecting. */
|
||||
bool adv_directed_high_duty_enabled; /**< Enable or disable high duty direct advertising mode. */
|
||||
bool adv_directed_low_duty_enabled; /**< Enable or disable low duty direct advertising mode. */
|
||||
bool adv_fast_enabled; /**< Enable or disable fast advertising mode. */
|
||||
bool adv_slow_enabled; /**< Enable or disable slow advertising mode. */
|
||||
bool adv_extended_enabled; /**< Enable or disable extended advertising. */
|
||||
uint16_t adv_directed_low_duty_interval; /**< Advertising interval for directed advertising. */
|
||||
uint16_t adv_directed_low_duty_timeout; /**< Time-out (number of tries) for direct advertising. */
|
||||
uint16_t adv_fast_interval; /**< Advertising interval for fast advertising. */
|
||||
uint16_t adv_fast_timeout; /**< Time-out (in units of 10ms) for fast advertising. */
|
||||
uint16_t adv_slow_interval; /**< Advertising interval for slow advertising. */
|
||||
uint16_t adv_slow_timeout; /**< Time-out (in units of 10ms) for slow advertising. */
|
||||
ble_gap_le_phy_value_t adv_secondary_phy; /**< PHY for the secondary (extended) advertising. */
|
||||
ble_gap_le_phy_value_t adv_primary_phy; /**< PHY for the primary advertising. */
|
||||
} ble_adv_mode_cfg_t;
|
||||
|
||||
/**@brief Avertising initialization. */
|
||||
typedef struct
|
||||
{
|
||||
ble_data_t adv_data; /**< Advertising data. */
|
||||
ble_data_t srp_data; /**< Scan response data. */
|
||||
ble_adv_mode_cfg_t adv_mode_cfg; /**< Advertising mode config. */
|
||||
ble_adv_evt_handler_t evt_handler; /**< Advertising event handler. */
|
||||
ble_adv_err_handler_t err_handler; /**< Advertising error handler. */
|
||||
} ble_adv_init_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup BLE_ADVERTISING_FUNCTION Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Initialize BLE advertising module.
|
||||
*
|
||||
* @param[in] p_adv_init: Pointer to advertising init params.
|
||||
*
|
||||
* @return Result of ble advertising initialization.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_advertising_init(ble_adv_init_t *p_adv_init);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Start advertising.
|
||||
*
|
||||
* @param[in] adv_mode: Advertising mode.
|
||||
*
|
||||
* @return Result of ble advertising start.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_advertising_start(ble_adv_mode_t adv_mode);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Update the advertising data.
|
||||
*
|
||||
* @param[in] p_adv_data: Pointer to the new advertising data, or null if advertising data dosen't need to be updated.
|
||||
* @param[in] adv_data_len: Length of the new advertising data.
|
||||
* @param[in] p_srsp_data: Pointer to the new scan response data, or null if advertising data dosen't need to be updated.
|
||||
* @param[in] srsp_data_len: Length of the new scan response data.
|
||||
*
|
||||
* @return Result of adv data update.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_advertising_adv_data_update(const uint8_t *p_adv_data, uint16_t adv_data_len, const uint8_t *p_srsp_data, uint16_t srsp_data_len);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Fill direct advertising peer address.
|
||||
*
|
||||
* @param[in] p_peer_addr: Pointer to peer address.
|
||||
*
|
||||
* @return Result of address check.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_advertising_dir_addr_fill(ble_gap_bdaddr_t *p_peer_addr);
|
||||
|
||||
void ble_advertising_evt_on_ble_capture(const ble_evt_t *p_evt);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
kernel_module("ble_connect") {
|
||||
sources = [ "ble_connect.c" ]
|
||||
}
|
||||
@@ -0,0 +1,610 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file ble_connect.c
|
||||
*
|
||||
* @brief BLE Connect Module API
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "ble_module_config.h"
|
||||
#if BLE_CONNECT_ENABLE
|
||||
#include "ble_connect.h"
|
||||
#include "app_timer.h"
|
||||
#include "utility.h"
|
||||
|
||||
/*
|
||||
* DEFINES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
/**@brief Gapm config data. */
|
||||
#define BLE_CONN_INTERVAL_MIN 0x0006 /**< Minimum value for the connection interval(7.5 ms). */
|
||||
#define BLE_CONN_INTERVAL_MAX 0x0C80 /**< Maximum value for the connection interval(4 s). */
|
||||
#define BLE_CONN_LATENCY_MAX 0x01F3 /**< Maximum value for the slave latency(499). */
|
||||
#define BLE_CONN_TIMEOUT_MIN 0x000A /**< Minimum value for the supervision timeout(100ms s). */
|
||||
#define BLE_CONN_TIMEOUT_MAX 0x0C80 /**< Maximum value for the supervision timeout(32 s). */
|
||||
#define BLE_TIMER_TIMEOUT_MAX 4000000 /**< Maximum value for the app_timer timeout(4000 s). */
|
||||
|
||||
/*
|
||||
* STRUCTURES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
/**@brief BLE Connect Module environment variable. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t act_conn_idx;
|
||||
bool conn_param_manage_enable;
|
||||
ble_conn_link_info_t link_info[BLE_CONN_LINK_CNT_MAX];
|
||||
uint32_t first_conn_param_update_delay;
|
||||
uint32_t next_conn_param_update_delay;
|
||||
uint8_t max_conn_param_update_count;
|
||||
bool disconnect_on_fail;
|
||||
ble_conn_evt_handler_t evt_handler;
|
||||
ble_conn_err_handler_t err_handler;
|
||||
} ble_conn_env_t;
|
||||
|
||||
/*
|
||||
* LOCAL VARIABLE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static ble_conn_env_t s_conn_env;
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static bool is_conn_param_ok(ble_gap_conn_param_t const * p_preferred_conn_param,
|
||||
ble_gap_evt_conn_param_updated_t const * p_actual_conn_param,
|
||||
uint16_t max_slave_latency_err,
|
||||
uint16_t max_sup_timeout_err)
|
||||
{
|
||||
uint32_t max_allowed_sl = p_preferred_conn_param->slave_latency + max_slave_latency_err;
|
||||
uint32_t min_allowed_sl = p_preferred_conn_param->slave_latency
|
||||
- MIN(max_slave_latency_err, p_preferred_conn_param->slave_latency);
|
||||
uint32_t max_allowed_to = p_preferred_conn_param->sup_timeout + max_sup_timeout_err;
|
||||
uint32_t min_allowed_to = p_preferred_conn_param->sup_timeout
|
||||
- MIN(max_sup_timeout_err, p_preferred_conn_param->sup_timeout);
|
||||
|
||||
// Check if interval is within the acceptable range.
|
||||
// NOTE: Using max_conn_interval in the received event data because this contains
|
||||
// the client's connection interval.
|
||||
if ((p_actual_conn_param->conn_interval < p_preferred_conn_param->interval_min) ||
|
||||
(p_actual_conn_param->conn_interval > p_preferred_conn_param->interval_max))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if slave latency is within the acceptable deviation.
|
||||
if ((p_actual_conn_param->slave_latency < min_allowed_sl)
|
||||
|| (p_actual_conn_param->slave_latency > max_allowed_sl))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if supervision timeout is within the acceptable deviation.
|
||||
if ((p_actual_conn_param->sup_timeout < min_allowed_to) || (p_actual_conn_param->sup_timeout > max_allowed_to))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ble_connect_err_on_ble_capture(uint8_t err_code)
|
||||
{
|
||||
if (s_conn_env.err_handler && err_code)
|
||||
{
|
||||
s_conn_env.err_handler(err_code);
|
||||
}
|
||||
}
|
||||
|
||||
static bool send_update_request(uint8_t conn_idx, ble_gap_conn_param_t * p_new_conn_param)
|
||||
{
|
||||
sdk_err_t error_code;
|
||||
|
||||
ble_gap_conn_update_param_t conn_update_param;
|
||||
memcpy(&conn_update_param, p_new_conn_param, sizeof(ble_gap_conn_param_t));
|
||||
conn_update_param.ce_len = 0;
|
||||
|
||||
error_code = ble_gap_conn_param_update(conn_idx, &conn_update_param);
|
||||
if ((error_code != SDK_SUCCESS) && (error_code != SDK_ERR_BUSY)) // SDK_ERR_BUSY means another conn_param_update request is pending.
|
||||
{
|
||||
ble_connect_err_on_ble_capture(error_code);
|
||||
}
|
||||
|
||||
return (error_code == SDK_SUCCESS);
|
||||
}
|
||||
|
||||
static void update_timeout_handler(void *p_context)
|
||||
{
|
||||
uint32_t conn_idx = (uint32_t)p_context;
|
||||
|
||||
if (BLE_CONN_STATE_CONNECTED == s_conn_env.link_info[conn_idx].conn_state)
|
||||
{
|
||||
if (s_conn_env.link_info[conn_idx].param_ok)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Check if we have reached the maximum number of attempts
|
||||
if (s_conn_env.link_info[conn_idx].update_count < s_conn_env.max_conn_param_update_count)
|
||||
{
|
||||
bool update_sent = send_update_request(conn_idx, &s_conn_env.link_info[conn_idx].pref_conn_param);
|
||||
if (update_sent)
|
||||
{
|
||||
s_conn_env.link_info[conn_idx].update_count++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s_conn_env.link_info[conn_idx].update_count = 0;
|
||||
|
||||
// Negotiation failed, disconnect automatically if this has been configured
|
||||
if (s_conn_env.disconnect_on_fail)
|
||||
{
|
||||
sdk_err_t error_code;
|
||||
|
||||
error_code = ble_gap_disconnect_with_reason(conn_idx, BLE_GAP_HCI_CONN_INTERVAL_UNACCEPTABLE);
|
||||
|
||||
ble_connect_err_on_ble_capture(error_code);
|
||||
}
|
||||
|
||||
// Notify the application that the procedure has failed
|
||||
if (s_conn_env.evt_handler)
|
||||
{
|
||||
ble_conn_evt_t conn_evt;
|
||||
|
||||
conn_evt.evt_type = BLE_CONN_EVT_PARAM_NEGO_FAILED;
|
||||
conn_evt.conn_idx = conn_idx;
|
||||
|
||||
s_conn_env.evt_handler(&conn_evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void conn_param_negotiation(uint8_t conn_idx)
|
||||
{
|
||||
// Start negotiation if the received connection parameters are not acceptable
|
||||
if (!s_conn_env.link_info[conn_idx].param_ok)
|
||||
{
|
||||
sdk_err_t error_code;
|
||||
uint32_t timeout_ticks;
|
||||
|
||||
if (0 == s_conn_env.link_info[conn_idx].update_count)
|
||||
{
|
||||
// First connection parameter update
|
||||
timeout_ticks = s_conn_env.first_conn_param_update_delay;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeout_ticks = s_conn_env.next_conn_param_update_delay;
|
||||
}
|
||||
|
||||
app_timer_stop(s_conn_env.link_info[conn_idx].timer_id);
|
||||
error_code = app_timer_start(s_conn_env.link_info[conn_idx].timer_id, timeout_ticks, (void *)(uint32_t)conn_idx);
|
||||
ble_connect_err_on_ble_capture(error_code);
|
||||
}
|
||||
else
|
||||
{
|
||||
s_conn_env.link_info[conn_idx].update_count = 0;
|
||||
|
||||
// Notify the application that the procedure has succeeded
|
||||
if (s_conn_env.evt_handler != NULL)
|
||||
{
|
||||
ble_conn_evt_t evt;
|
||||
|
||||
evt.evt_type = BLE_CONN_EVT_PARAM_NEGO_SUCCEEDED;
|
||||
evt.conn_idx = conn_idx;
|
||||
s_conn_env.evt_handler(&evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_conn_established(uint8_t conn_idx, const ble_gap_evt_connected_t *p_conn_param)
|
||||
{
|
||||
if (conn_idx >= BLE_CONN_LINK_CNT_MAX)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
s_conn_env.link_info[conn_idx].conn_state = BLE_CONN_STATE_CONNECTED;
|
||||
s_conn_env.link_info[conn_idx].local_role = p_conn_param->ll_role;
|
||||
s_conn_env.link_info[conn_idx].conn_param.conn_interval = p_conn_param->conn_interval;
|
||||
s_conn_env.link_info[conn_idx].conn_param.slave_latency = p_conn_param->slave_latency;
|
||||
s_conn_env.link_info[conn_idx].conn_param.sup_timeout = p_conn_param->sup_timeout;
|
||||
s_conn_env.link_info[conn_idx].peer_addr.addr_type = p_conn_param->peer_addr_type;
|
||||
memcpy(&s_conn_env.link_info[conn_idx].peer_addr.gap_addr, &p_conn_param->peer_addr, sizeof(ble_gap_addr_t));
|
||||
|
||||
|
||||
if (BLE_GAP_LL_ROLE_SLAVE == s_conn_env.link_info[conn_idx].local_role)
|
||||
{
|
||||
ble_gap_evt_conn_param_updated_t conn_updated_param;
|
||||
memcpy(&conn_updated_param, &p_conn_param->conn_interval, sizeof(conn_updated_param));
|
||||
|
||||
s_conn_env.link_info[conn_idx].param_ok = is_conn_param_ok(&s_conn_env.link_info[conn_idx].pref_conn_param,
|
||||
&conn_updated_param,
|
||||
BLE_CONN_PARAM_MAX_SLAVE_LATENCY_DEVIATION,
|
||||
BLE_CONN_PARAM_MAX_SUPERVISION_TIMEOUT_DEVIATION);
|
||||
|
||||
if (s_conn_env.conn_param_manage_enable)
|
||||
{
|
||||
conn_param_negotiation(conn_idx);
|
||||
}
|
||||
else if (!s_conn_env.link_info[conn_idx].param_ok && s_conn_env.disconnect_on_fail)
|
||||
{
|
||||
sdk_err_t error_code;
|
||||
|
||||
error_code = ble_gap_disconnect_with_reason(conn_idx, BLE_GAP_HCI_CONN_INTERVAL_UNACCEPTABLE);
|
||||
ble_connect_err_on_ble_capture(error_code);
|
||||
}
|
||||
}
|
||||
if (s_conn_env.evt_handler)
|
||||
{
|
||||
ble_conn_evt_t conn_evt;
|
||||
|
||||
conn_evt.evt_type = BLE_CONN_EVT_CONNECTED;
|
||||
conn_evt.conn_idx = conn_idx;
|
||||
conn_evt.param.p_link_info = &s_conn_env.link_info[conn_idx];
|
||||
|
||||
s_conn_env.evt_handler(&conn_evt);
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_conn_terminated(uint8_t conn_idx, uint8_t reason)
|
||||
{
|
||||
if (conn_idx >= BLE_CONN_LINK_CNT_MAX)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
app_timer_id_t timer_id_temp = s_conn_env.link_info[conn_idx].timer_id;
|
||||
ble_gap_conn_param_t pref_conn_param_temp = s_conn_env.link_info[conn_idx].pref_conn_param;
|
||||
|
||||
memset(&s_conn_env.link_info[conn_idx], 0, sizeof(ble_conn_link_info_t));
|
||||
s_conn_env.link_info[conn_idx].timer_id = timer_id_temp;
|
||||
s_conn_env.link_info[conn_idx].conn_state = BLE_CONN_STATE_DISCONNECTED;
|
||||
memcpy(&s_conn_env.link_info[conn_idx].pref_conn_param, &pref_conn_param_temp, sizeof(ble_gap_conn_param_t));
|
||||
|
||||
app_timer_stop(s_conn_env.link_info[conn_idx].timer_id);
|
||||
|
||||
if (conn_idx == s_conn_env.act_conn_idx)
|
||||
{
|
||||
s_conn_env.act_conn_idx = BLE_GAP_INVALID_CONN_INDEX;
|
||||
}
|
||||
|
||||
if (s_conn_env.evt_handler)
|
||||
{
|
||||
ble_conn_evt_t conn_evt;
|
||||
|
||||
conn_evt.evt_type = BLE_CONN_EVT_DISCONNECTED;
|
||||
conn_evt.conn_idx = conn_idx;
|
||||
conn_evt.param.disconn_reason = reason;
|
||||
|
||||
s_conn_env.evt_handler(&conn_evt);
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_conn_param_updated(uint8_t conn_idx, const ble_gap_evt_conn_param_updated_t *p_conn_param_updated_info)
|
||||
{
|
||||
if (conn_idx >= BLE_CONN_LINK_CNT_MAX)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&s_conn_env.link_info[conn_idx].conn_param, p_conn_param_updated_info, sizeof(ble_conn_param_t));
|
||||
|
||||
if (BLE_GAP_LL_ROLE_SLAVE == s_conn_env.link_info[conn_idx].local_role)
|
||||
{
|
||||
s_conn_env.link_info[conn_idx].param_ok = is_conn_param_ok(&s_conn_env.link_info[conn_idx].pref_conn_param,
|
||||
p_conn_param_updated_info,
|
||||
BLE_CONN_PARAM_MAX_SLAVE_LATENCY_DEVIATION,
|
||||
BLE_CONN_PARAM_MAX_SUPERVISION_TIMEOUT_DEVIATION);
|
||||
if (s_conn_env.conn_param_manage_enable)
|
||||
{
|
||||
conn_param_negotiation(conn_idx);
|
||||
}
|
||||
else if (!s_conn_env.link_info[conn_idx].param_ok && s_conn_env.disconnect_on_fail)
|
||||
{
|
||||
sdk_err_t error_code;
|
||||
|
||||
error_code = ble_gap_disconnect_with_reason(conn_idx, BLE_GAP_HCI_CONN_INTERVAL_UNACCEPTABLE);
|
||||
ble_connect_err_on_ble_capture(error_code);
|
||||
}
|
||||
}
|
||||
|
||||
// Interval = 0x4000 means thats connect param update request is rejected by master.
|
||||
if (s_conn_env.evt_handler && p_conn_param_updated_info->conn_interval != 0x4000)
|
||||
{
|
||||
ble_conn_evt_t conn_evt;
|
||||
|
||||
conn_evt.evt_type = BLE_CONN_EVT_PATAM_UPDATED;
|
||||
conn_evt.conn_idx = conn_idx;
|
||||
conn_evt.param.p_update_param = (ble_conn_param_t *)p_conn_param_updated_info;
|
||||
|
||||
s_conn_env.evt_handler(&conn_evt);
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_conn_link_encrypted(uint8_t conn_idx, uint8_t enc_ind)
|
||||
{
|
||||
if (conn_idx >= BLE_CONN_LINK_CNT_MAX)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
s_conn_env.link_info[conn_idx].is_encrypt = true;
|
||||
}
|
||||
|
||||
static sdk_err_t conn_init_param_check(ble_conn_init_t *p_conn_init)
|
||||
{
|
||||
if (NULL == p_conn_init)
|
||||
{
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
if (NULL != p_conn_init->p_conn_param)
|
||||
{
|
||||
ble_gap_conn_param_t *p_conn_param = p_conn_init->p_conn_param;
|
||||
if (p_conn_param->interval_max > BLE_CONN_INTERVAL_MAX || p_conn_param->interval_min < BLE_CONN_INTERVAL_MIN ||
|
||||
p_conn_param->interval_max < p_conn_param->interval_min || p_conn_param->slave_latency > BLE_CONN_LATENCY_MAX ||
|
||||
p_conn_param->sup_timeout > BLE_CONN_TIMEOUT_MAX || p_conn_param->sup_timeout < BLE_CONN_TIMEOUT_MIN)
|
||||
{
|
||||
return SDK_ERR_INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
if (p_conn_init->first_conn_param_update_delay > BLE_TIMER_TIMEOUT_MAX ||
|
||||
p_conn_init->next_conn_param_update_delay > BLE_TIMER_TIMEOUT_MAX)
|
||||
{
|
||||
return SDK_ERR_INVALID_PARAM;
|
||||
}
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
*******************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_connect_init(ble_conn_init_t *p_conn_init)
|
||||
{
|
||||
sdk_err_t error_code;
|
||||
|
||||
error_code = conn_init_param_check(p_conn_init);
|
||||
RET_VERIFY_SUCCESS(error_code);
|
||||
|
||||
memset(&s_conn_env, 0, sizeof(s_conn_env));
|
||||
|
||||
s_conn_env.act_conn_idx = BLE_GAP_INVALID_CONN_INDEX;
|
||||
s_conn_env.conn_param_manage_enable = p_conn_init->conn_param_manage_enable;
|
||||
if (s_conn_env.conn_param_manage_enable)
|
||||
{
|
||||
if (p_conn_init->p_conn_param != NULL)
|
||||
{
|
||||
// Set the connection param in stack.
|
||||
error_code = ble_gap_ppcp_set(p_conn_init->p_conn_param);
|
||||
RET_VERIFY_SUCCESS(error_code);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the (default) connection param from stack.
|
||||
error_code = ble_gap_ppcp_get(p_conn_init->p_conn_param);
|
||||
RET_VERIFY_SUCCESS(error_code);
|
||||
}
|
||||
s_conn_env.first_conn_param_update_delay = p_conn_init->first_conn_param_update_delay;
|
||||
s_conn_env.next_conn_param_update_delay = p_conn_init->next_conn_param_update_delay;
|
||||
s_conn_env.max_conn_param_update_count = p_conn_init->max_conn_param_update_count;
|
||||
|
||||
for (uint32_t i = 0; i < BLE_CONN_LINK_CNT_MAX; i++)
|
||||
{
|
||||
memcpy(&s_conn_env.link_info[i].pref_conn_param, p_conn_init->p_conn_param, sizeof(ble_gap_conn_param_t));
|
||||
|
||||
error_code = app_timer_create(&s_conn_env.link_info[i].timer_id, ATIMER_ONE_SHOT,
|
||||
update_timeout_handler);
|
||||
RET_VERIFY_SUCCESS(error_code);
|
||||
}
|
||||
}
|
||||
|
||||
s_conn_env.disconnect_on_fail = p_conn_init->disconnect_on_fail;
|
||||
s_conn_env.evt_handler = p_conn_init->evt_handler;
|
||||
s_conn_env.err_handler = p_conn_init->err_handler;
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
uint8_t ble_connect_established_cnt_get(void)
|
||||
{
|
||||
uint8_t count = 0;
|
||||
|
||||
for (uint8_t i = 0; i < BLE_CONN_LINK_CNT_MAX; i++)
|
||||
{
|
||||
if (BLE_CONN_STATE_CONNECTED == s_conn_env.link_info[i].conn_state)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool ble_connect_is_connected(uint8_t conn_idx)
|
||||
{
|
||||
if (conn_idx >= BLE_CONN_LINK_CNT_MAX)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (BLE_CONN_STATE_CONNECTED == s_conn_env.link_info[conn_idx].conn_state)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
sdk_err_t ble_connect_link_info_get(uint8_t conn_idx, ble_conn_link_info_t *p_link_info)
|
||||
{
|
||||
if (conn_idx >= BLE_CONN_LINK_CNT_MAX || NULL == p_link_info)
|
||||
{
|
||||
return SDK_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
memcpy(p_link_info, &s_conn_env.link_info[conn_idx], sizeof(ble_conn_link_info_t));
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
sdk_err_t ble_connect_active_link_set(uint8_t conn_idx)
|
||||
{
|
||||
if (conn_idx >= BLE_CONN_LINK_CNT_MAX || BLE_CONN_STATE_DISCONNECTED == s_conn_env.link_info[conn_idx].conn_state)
|
||||
{
|
||||
return SDK_ERR_INVALID_CONN_IDX;
|
||||
}
|
||||
|
||||
s_conn_env.act_conn_idx = conn_idx;
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
uint8_t ble_connect_active_link_get(void)
|
||||
{
|
||||
return s_conn_env.act_conn_idx;
|
||||
}
|
||||
|
||||
sdk_err_t ble_connect_all_to_do(ble_conn_all_link_exec_handler_t exec_handler)
|
||||
{
|
||||
if (NULL == exec_handler)
|
||||
{
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < BLE_CONN_LINK_CNT_MAX; i++)
|
||||
{
|
||||
if (BLE_CONN_STATE_CONNECTED == s_conn_env.link_info[i].conn_state)
|
||||
{
|
||||
exec_handler(i);
|
||||
}
|
||||
}
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
sdk_err_t ble_connect_next_link_idx_get(uint8_t cur_conn_idx, uint8_t *next_conn_idx)
|
||||
{
|
||||
if (cur_conn_idx >= BLE_CONN_LINK_CNT_MAX || NULL == next_conn_idx ||
|
||||
BLE_CONN_STATE_DISCONNECTED == s_conn_env.link_info[cur_conn_idx].conn_state)
|
||||
{
|
||||
*next_conn_idx = BLE_GAP_INVALID_CONN_INDEX;
|
||||
return SDK_ERR_INVALID_CONN_IDX;
|
||||
}
|
||||
|
||||
for (uint8_t i = cur_conn_idx + 1; ; i++)
|
||||
{
|
||||
if (i == BLE_CONN_LINK_CNT_MAX)
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (BLE_CONN_STATE_CONNECTED == s_conn_env.link_info[i].conn_state)
|
||||
{
|
||||
*next_conn_idx = i;
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sdk_err_t ble_connect_param_update_stop(void)
|
||||
{
|
||||
for (uint32_t i = 0; i < BLE_CONN_LINK_CNT_MAX; i++)
|
||||
{
|
||||
app_timer_stop(s_conn_env.link_info[i].timer_id);
|
||||
}
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
sdk_err_t ble_connect_param_change(uint8_t conn_idx, ble_gap_conn_param_t *p_new_conn_param)
|
||||
{
|
||||
sdk_err_t error_code = SDK_ERR_INVALID_CONN_IDX;
|
||||
|
||||
if (conn_idx >= BLE_CONN_LINK_CNT_MAX)
|
||||
{
|
||||
return SDK_ERR_INVALID_CONN_IDX;
|
||||
}
|
||||
|
||||
if (p_new_conn_param == NULL)
|
||||
{
|
||||
p_new_conn_param = &s_conn_env.link_info[conn_idx].pref_conn_param;
|
||||
}
|
||||
|
||||
if (BLE_CONN_STATE_CONNECTED == s_conn_env.link_info[conn_idx].conn_state)
|
||||
{
|
||||
ble_gap_conn_update_param_t conn_update_param;
|
||||
memcpy(&conn_update_param, p_new_conn_param, sizeof(ble_gap_conn_param_t));
|
||||
conn_update_param.ce_len = 0;
|
||||
// Send request to master.
|
||||
error_code = ble_gap_conn_param_update(conn_idx, &conn_update_param);
|
||||
if (error_code == SDK_SUCCESS)
|
||||
{
|
||||
s_conn_env.link_info[conn_idx].param_ok = false;
|
||||
s_conn_env.link_info[conn_idx].update_count = 1;
|
||||
s_conn_env.link_info[conn_idx].pref_conn_param = *p_new_conn_param;
|
||||
}
|
||||
}
|
||||
|
||||
return error_code;
|
||||
}
|
||||
|
||||
void ble_connect_evt_on_ble_capture(const ble_evt_t *p_evt)
|
||||
{
|
||||
switch (p_evt->evt_id)
|
||||
{
|
||||
case BLE_GAPC_EVT_CONNECTED:
|
||||
ble_conn_established(p_evt->evt.gapc_evt.index, &(p_evt->evt.gapc_evt.params.connected));
|
||||
break;
|
||||
|
||||
case BLE_GAPC_EVT_DISCONNECTED:
|
||||
ble_conn_terminated(p_evt->evt.gapc_evt.index, p_evt->evt.gapc_evt.params.disconnected.reason);
|
||||
break;
|
||||
|
||||
case BLE_GAPC_EVT_CONN_PARAM_UPDATED:
|
||||
ble_conn_param_updated(p_evt->evt.gapc_evt.index, &(p_evt->evt.gapc_evt.params.conn_param_updated));
|
||||
break;
|
||||
|
||||
case BLE_SEC_EVT_LINK_ENCRYPTED:
|
||||
ble_conn_link_encrypted(p_evt->evt.gapc_evt.index, p_evt->evt_status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,289 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file ble_connect.h
|
||||
*
|
||||
* @brief BLE Connect Module Header
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __BLE_CONNECT_H__
|
||||
#define __BLE_CONNECT_H__
|
||||
|
||||
#include "gr_includes.h"
|
||||
#include "app_timer.h"
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup BLE_CONNECT_MAROC Defines
|
||||
* @{
|
||||
*/
|
||||
#define RET_VERIFY_SUCCESS(RET_CODE) \
|
||||
do \
|
||||
{ \
|
||||
if (RET_CODE != SDK_SUCCESS) \
|
||||
{ \
|
||||
return RET_CODE; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define BLE_CONN_PARAM_MAX_SLAVE_LATENCY_DEVIATION 10 /**< The largest acceptable deviation in slave latency. */
|
||||
#define BLE_CONN_PARAM_MAX_SUPERVISION_TIMEOUT_DEVIATION 100 /**< The largest acceptable deviation (in 10 ms units) in supervision timeout. */
|
||||
|
||||
|
||||
#ifdef CFG_MAX_CONNECTIONS
|
||||
#define BLE_CONN_LINK_CNT_MAX CFG_MAX_CONNECTIONS
|
||||
#else
|
||||
#define BLE_CONN_LINK_CNT_MAX 10
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup BLE_CONNECT_ENUM Enumerations
|
||||
* @{
|
||||
*/
|
||||
/**@brief BLE connect state. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_CONN_STATE_DISCONNECTED, /**< BLE link disconnected state. */
|
||||
BLE_CONN_STATE_CONNECTED, /**< BLE link connected state. */
|
||||
} ble_conn_state_t;
|
||||
|
||||
/**@brief BLE connect events type. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_CONN_EVT_INVALID, /**< Invalid connect event. */
|
||||
BLE_CONN_EVT_CONNECTED, /**< Connected event. */
|
||||
BLE_CONN_EVT_DISCONNECTED, /**< Disconnected event. */
|
||||
BLE_CONN_EVT_PATAM_UPDATED, /**< Connect param updated event. */
|
||||
BLE_CONN_EVT_PPCP_GET_FAIL, /**< PPCP get fail. */
|
||||
BLE_CONN_EVT_PARAM_NEGO_FAILED, /**< Negotiation procedure failed. */
|
||||
BLE_CONN_EVT_PARAM_NEGO_SUCCEEDED /**< Negotiation procedure succeeded. */
|
||||
} ble_conn_evt_type_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup BLE_CONNECT_TYPEDEF Typedefs
|
||||
* @{
|
||||
*/
|
||||
/**@brief BLE connect role of LL layer. */
|
||||
typedef ble_gap_ll_role_type_t ble_conn_role_t;
|
||||
|
||||
/**@brief BLE connect parameter. */
|
||||
typedef ble_gap_evt_conn_param_updated_t ble_conn_param_t;
|
||||
|
||||
/**@brief All connected link need to execute handler type. */
|
||||
typedef void (*ble_conn_all_link_exec_handler_t)(uint8_t conn_idx);
|
||||
|
||||
/**@brief BLE connect error handler type. */
|
||||
typedef void (*ble_conn_err_handler_t)(uint8_t err_code);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup BLE_CONNECT_STRUCT Structures
|
||||
* @{
|
||||
*/
|
||||
/**@brief BLE connect link information. */
|
||||
typedef struct
|
||||
{
|
||||
bool is_encrypt; /**< Is encrypt or not. */
|
||||
ble_conn_state_t conn_state; /**< BLE connect state. */
|
||||
ble_conn_role_t local_role; /**< Local BLE LL role. */
|
||||
ble_gap_bdaddr_t peer_addr; /**< Peer address. */
|
||||
ble_conn_param_t conn_param; /**< BLE connect parameters. */
|
||||
ble_gap_conn_param_t pref_conn_param; /**< BLE prefer connect parameters. */
|
||||
uint8_t param_ok; /**< Whether the current connection parameters on this link are acceptable. */
|
||||
uint8_t update_count; /**< The number of times the connection parameters have been attempted
|
||||
negotiated on this link. */
|
||||
app_timer_id_t timer_id; /**< Timer id of connect parameter update. */
|
||||
} ble_conn_link_info_t;
|
||||
|
||||
/**@brief BLE connect event information. */
|
||||
typedef struct
|
||||
{
|
||||
ble_conn_evt_type_t evt_type;
|
||||
uint8_t conn_idx;
|
||||
union
|
||||
{
|
||||
ble_conn_link_info_t *p_link_info;
|
||||
uint8_t disconn_reason;
|
||||
ble_conn_param_t *p_update_param;
|
||||
} param;
|
||||
}ble_conn_evt_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup BLE_CONNECT_TYPEDEF Typedefs
|
||||
* @{
|
||||
*/
|
||||
/**@brief BLE connect event handler type. */
|
||||
typedef void (*ble_conn_evt_handler_t)(ble_conn_evt_t *p_evt);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup BLE_CONNECT_STRUCT Structures
|
||||
* @{
|
||||
*/
|
||||
/**@brief BLE connect initialization. */
|
||||
typedef struct
|
||||
{
|
||||
bool conn_param_manage_enable; /**< Enable or disable connect param auto update. */
|
||||
ble_gap_conn_param_t *p_conn_param; /**< Pointer to the connection parameters desired by the application.It will be fetched from host if set to NULL. */
|
||||
uint32_t first_conn_param_update_delay; /**< Time from connect to first time ble_gap_conn_param_update is called (in 1 ms). */
|
||||
uint32_t next_conn_param_update_delay; /**< Time between each call to ble_gap_conn_param_update after the first (in 1 ms). */
|
||||
uint8_t max_conn_param_update_count; /**< Number of attempts before giving up the negotiation. */
|
||||
bool disconnect_on_fail; /**< Set to TRUE if a failed connection parameters update shall cause an automatic disconnection. */
|
||||
ble_conn_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Connection. */
|
||||
ble_conn_err_handler_t err_handler; /**< Function to be called in case of an error. */
|
||||
} ble_conn_init_t;
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup BLE_CONNECT_FUNCTION Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Initialize BLE connect module.
|
||||
*
|
||||
* @param[in] p_conn_init: Pointer to initialization params.
|
||||
*
|
||||
* @return Result of ble connect initialization.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_connect_init(ble_conn_init_t *p_conn_init);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Get count of established BLE connect link.
|
||||
*
|
||||
* @return Count of established ble connect link.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
uint8_t ble_connect_established_cnt_get(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Check BLE connect link is connected or not.
|
||||
*
|
||||
* @param[in] conn_idx: Index of connection.
|
||||
*
|
||||
* @return Result of check.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
bool ble_connect_is_connected(uint8_t conn_idx);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Get connect link information.
|
||||
*
|
||||
* @param[in] conn_idx: Index of connection.
|
||||
* @param[in\out] p_link_info: Buffer for save information get.
|
||||
*
|
||||
* @return Result of get.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_connect_link_info_get(uint8_t conn_idx, ble_conn_link_info_t *p_link_info);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Set active connect link.
|
||||
*
|
||||
* @param[in] conn_idx: Index of connection.
|
||||
*
|
||||
* @return Result of set.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_connect_active_link_set(uint8_t conn_idx);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Set active connect link.
|
||||
*
|
||||
* @param[in] conn_idx: Index of connection.
|
||||
*
|
||||
* @return Result of get.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
uint8_t ble_connect_active_link_get(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief All connected link need to execute handler.
|
||||
*
|
||||
* @param[in] exec_handler: Execute handler.
|
||||
*
|
||||
* @return Result of check.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_connect_all_to_do(ble_conn_all_link_exec_handler_t exec_handler);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Get next connected link index.
|
||||
*
|
||||
* @param[in] cur_conn_idx: Index of cur_connection.
|
||||
* @param[in] next_conn_idx: Pointer to next connected link index.
|
||||
*
|
||||
* @return Result of get..
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_connect_next_link_idx_get(uint8_t cur_conn_idx, uint8_t *next_conn_idx);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Function for stopping the Connection Parameters manage module.
|
||||
|
||||
* @return Result of stopping the Connection Parameters module.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_connect_param_update_stop(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Initialize parameter update request.
|
||||
*
|
||||
* @param[in] conn_idx: Index of connection.
|
||||
*
|
||||
* @param[in] p_new_param: Pointer to the new connect parameter.
|
||||
*
|
||||
* @return Result of ble advertising initialization.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_connect_param_change(uint8_t conn_idx, ble_gap_conn_param_t *p_new_param);
|
||||
|
||||
void ble_connect_evt_on_ble_capture(const ble_evt_t *p_evt);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
kernel_module("ble_gatt_service") {
|
||||
sources = [ "ble_gatt_service.c" ]
|
||||
}
|
||||
+675
@@ -0,0 +1,675 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file ble_gatt_service.c
|
||||
*
|
||||
* @brief BLE GATT Service Module API
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "ble_gatt_service.h"
|
||||
#include "ble_prf_types.h"
|
||||
#include "custom_config.h"
|
||||
|
||||
|
||||
/*
|
||||
* DEFINES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#define BLE_GATTS_ATT_ELEMENT_SIZE sizeof(attm_desc_128_t)
|
||||
#define BLE_GATTS_HADNLE_PTR_SIZE sizeof(uint16_t *)
|
||||
#define BLE_GATTS_INVALID_SERV_IDX 0xff
|
||||
|
||||
#define BLE_GATT_REALLOC_VERIFY(ptr, offset, size) \
|
||||
do \
|
||||
{ \
|
||||
if (NULL == ptr) \
|
||||
{ \
|
||||
return SDK_ERR_NO_RESOURCES; \
|
||||
} \
|
||||
memset(&ptr[offset], 0, size); \
|
||||
} while(0);
|
||||
|
||||
#define BLE_GATT_MALLOC_VERIFY(ptr, size) \
|
||||
do \
|
||||
{ \
|
||||
if (NULL == ptr) \
|
||||
{ \
|
||||
return SDK_ERR_NO_RESOURCES; \
|
||||
} \
|
||||
memset(ptr, 0, size); \
|
||||
} while(0);
|
||||
|
||||
/*
|
||||
* STRUCTURES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t start_hdl; /**< Start handle. */
|
||||
uint16_t end_hdl; /**< End handle. */
|
||||
ble_gatts_handler_t handlers; /**< Att handlers. */
|
||||
} ble_gatts_serv_info_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
uint8_t inc_serv_num; /**< Number of include services. */
|
||||
uint16_t **p_inc_hdl_tab; /**< Pointer to include service handle pointer table. */
|
||||
uint16_t **p_att_hdl_tab; /**< Pointer to attributehandle pointer table. */
|
||||
attm_desc_128_t *p_db_tab; /**< Pointer to db table. */
|
||||
ble_att_uuid_t uuid; /**< Service UUID. */
|
||||
uint8_t att_num; /**< Number of attributes. */
|
||||
} ble_gatts_db_info_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t serv_num;
|
||||
uint16_t start_hdl;
|
||||
ble_gatts_serv_info_t *p_serv_info;
|
||||
} ble_gatts_serv_env_t;
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DECLARATION
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static ble_err_t ble_gatts_serv_load(void);
|
||||
static void ble_gatts_read_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_read_req);
|
||||
static void ble_gatts_write_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_write_req);
|
||||
static void ble_gatts_prep_write_cb(uint8_t conn_idx, const gatts_prep_write_req_cb_t *p_prep_write_req);
|
||||
static void ble_gatts_ntf_ind_cplt_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind);
|
||||
static void ble_gatts_cccd_recovery_cb(uint8_t conidx, uint16_t handle, uint16_t cccd_val);
|
||||
static void ble_gatts_on_connect_cb(uint8_t conn_idx);
|
||||
static void ble_gatts_on_disconnect_cb(uint8_t conn_idx, uint8_t reason);
|
||||
|
||||
/*
|
||||
* LOCAL VARIABLE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static ble_prf_manager_cbs_t s_mgr_cbs =
|
||||
{
|
||||
ble_gatts_serv_load,
|
||||
ble_gatts_on_connect_cb,
|
||||
ble_gatts_on_disconnect_cb
|
||||
};
|
||||
|
||||
static gatts_prf_cbs_t s_gatts_cbs =
|
||||
{
|
||||
ble_gatts_read_cb,
|
||||
ble_gatts_write_cb,
|
||||
ble_gatts_prep_write_cb,
|
||||
ble_gatts_ntf_ind_cplt_cb,
|
||||
ble_gatts_cccd_recovery_cb
|
||||
};
|
||||
|
||||
static const prf_server_info_t s_prf_info =
|
||||
{
|
||||
.max_connection_nb = CFG_MAX_CONNECTIONS,
|
||||
.manager_cbs = &s_mgr_cbs,
|
||||
.gatts_prf_cbs = &s_gatts_cbs
|
||||
};
|
||||
|
||||
static uint8_t s_create_serv_idx;
|
||||
static uint8_t s_load_serv_idx;
|
||||
static ble_gatts_db_info_t *s_p_db_info_tab;
|
||||
static ble_gatts_serv_env_t s_gatts_serv_env;
|
||||
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static uint8_t ble_gatts_serv_indx_find(uint16_t handle)
|
||||
{
|
||||
for (uint8_t i = 0; i < s_gatts_serv_env.serv_num; i++)
|
||||
{
|
||||
if (handle >= s_gatts_serv_env.p_serv_info[i].start_hdl &&
|
||||
handle <= s_gatts_serv_env.p_serv_info[i].end_hdl)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return BLE_GATTS_INVALID_SERV_IDX;
|
||||
}
|
||||
|
||||
extern uint8_t fpb_save_state(void);
|
||||
extern void fpb_load_state(uint8_t state);
|
||||
|
||||
static ble_err_t ble_gatts_serv_load(void)
|
||||
{
|
||||
fpb_load_state(0);
|
||||
sdk_err_t error_code;
|
||||
gatts_create_db_t gatts_db;
|
||||
uint8_t uuid[] = BLE_ATT_16_TO_128_ARRAY(s_p_db_info_tab[s_load_serv_idx].uuid.uuid.uuid16);
|
||||
|
||||
|
||||
memset(&gatts_db, 0, sizeof(gatts_create_db_t));
|
||||
|
||||
s_gatts_serv_env.p_serv_info[s_load_serv_idx].start_hdl = PRF_INVALID_HANDLE;
|
||||
|
||||
if (s_p_db_info_tab[s_load_serv_idx].uuid.type == BLE_ATT_UUID_128)
|
||||
{
|
||||
gatts_db.uuid = s_p_db_info_tab[s_load_serv_idx].uuid.uuid.uuid128;
|
||||
gatts_db.srvc_perm = SRVC_UUID_TYPE_SET(UUID_TYPE_128);
|
||||
}
|
||||
else
|
||||
{
|
||||
gatts_db.uuid = uuid;
|
||||
gatts_db.srvc_perm = 0;
|
||||
}
|
||||
|
||||
gatts_db.shdl = &s_gatts_serv_env.p_serv_info[s_load_serv_idx].start_hdl;
|
||||
gatts_db.attr_tab_cfg = NULL;
|
||||
gatts_db.max_nb_attr = s_p_db_info_tab[s_load_serv_idx].att_num;
|
||||
gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_128;
|
||||
gatts_db.attr_tab.attr_tab_128 = s_p_db_info_tab[s_load_serv_idx].p_db_tab;
|
||||
gatts_db.inc_srvc_num = s_p_db_info_tab[s_load_serv_idx].inc_serv_num;
|
||||
|
||||
for (uint8_t i = 0; i < gatts_db.inc_srvc_num; i++)
|
||||
{
|
||||
gatts_db.inc_srvc_handle[i] = s_p_db_info_tab[s_load_serv_idx].p_inc_hdl_tab[i];
|
||||
}
|
||||
|
||||
error_code = ble_gatts_srvc_db_create(&gatts_db);
|
||||
|
||||
if (SDK_SUCCESS == error_code)
|
||||
{
|
||||
s_gatts_serv_env.p_serv_info[s_load_serv_idx].end_hdl = s_gatts_serv_env.p_serv_info[s_load_serv_idx].start_hdl + \
|
||||
s_p_db_info_tab[s_load_serv_idx].att_num - 1;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < gatts_db.max_nb_attr; i++)
|
||||
{
|
||||
*(s_p_db_info_tab[s_load_serv_idx].p_att_hdl_tab[i]) = *(gatts_db.shdl) + i;
|
||||
}
|
||||
|
||||
if (s_p_db_info_tab[s_load_serv_idx].p_inc_hdl_tab)
|
||||
{
|
||||
BLE_GATT_SERV_FREE(s_p_db_info_tab[s_load_serv_idx].p_inc_hdl_tab);
|
||||
}
|
||||
|
||||
|
||||
BLE_GATT_SERV_FREE(s_p_db_info_tab[s_load_serv_idx].p_att_hdl_tab);
|
||||
BLE_GATT_SERV_FREE(s_p_db_info_tab[s_load_serv_idx].p_db_tab);
|
||||
|
||||
|
||||
s_load_serv_idx++;
|
||||
|
||||
if (s_load_serv_idx == s_gatts_serv_env.serv_num)
|
||||
{
|
||||
BLE_GATT_SERV_FREE(s_p_db_info_tab);
|
||||
}
|
||||
|
||||
fpb_save_state();
|
||||
return error_code;
|
||||
}
|
||||
|
||||
static void ble_gatts_read_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_read_req)
|
||||
{
|
||||
uint8_t sevr_idx = ble_gatts_serv_indx_find(p_read_req->handle);
|
||||
|
||||
if (sevr_idx != BLE_GATTS_INVALID_SERV_IDX &&
|
||||
s_gatts_serv_env.p_serv_info[sevr_idx].handlers.read_req_handler)
|
||||
{
|
||||
s_gatts_serv_env.p_serv_info[sevr_idx].handlers.read_req_handler(conn_idx, p_read_req->handle);
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_gatts_write_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_write_req)
|
||||
{
|
||||
uint8_t sevr_idx = ble_gatts_serv_indx_find(p_write_req->handle);
|
||||
|
||||
gatts_write_cfm_t cfm;
|
||||
|
||||
cfm.handle = p_write_req->handle;
|
||||
cfm.status = sevr_idx == BLE_GATTS_INVALID_SERV_IDX ? BLE_ATT_ERR_INVALID_HANDLE : BLE_SUCCESS;
|
||||
|
||||
ble_gatts_write_cfm(conn_idx, &cfm);
|
||||
|
||||
if (sevr_idx != BLE_GATTS_INVALID_SERV_IDX &&
|
||||
s_gatts_serv_env.p_serv_info[sevr_idx].handlers.write_req_handler)
|
||||
{
|
||||
s_gatts_serv_env.p_serv_info[sevr_idx].handlers.write_req_handler(conn_idx,
|
||||
p_write_req->handle,
|
||||
p_write_req->offset,
|
||||
p_write_req->value,
|
||||
p_write_req->length);
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_gatts_prep_write_cb(uint8_t conn_idx, const gatts_prep_write_req_cb_t *p_prep_write_req)
|
||||
{
|
||||
uint8_t sevr_idx = ble_gatts_serv_indx_find(p_prep_write_req->handle);
|
||||
|
||||
gatts_prep_write_cfm_t cfm;
|
||||
|
||||
cfm.handle = p_prep_write_req->handle;
|
||||
cfm.status = sevr_idx == BLE_GATTS_INVALID_SERV_IDX ? BLE_ATT_ERR_INVALID_HANDLE : BLE_SUCCESS;
|
||||
|
||||
ble_gatts_prepare_write_cfm(conn_idx, &cfm);
|
||||
}
|
||||
|
||||
static void ble_gatts_ntf_ind_cplt_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind)
|
||||
{
|
||||
uint8_t sevr_idx = ble_gatts_serv_indx_find(p_ntf_ind->handle);
|
||||
uint16_t h_offset = p_ntf_ind->handle - s_gatts_serv_env.start_hdl;
|
||||
|
||||
if (sevr_idx != BLE_GATTS_INVALID_SERV_IDX &&
|
||||
s_gatts_serv_env.p_serv_info[sevr_idx].handlers.ntf_ind_handler)
|
||||
{
|
||||
s_gatts_serv_env.p_serv_info[sevr_idx].handlers.ntf_ind_handler(conn_idx, status, p_ntf_ind->type, h_offset);
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_gatts_cccd_recovery_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val)
|
||||
{
|
||||
uint8_t sevr_idx = ble_gatts_serv_indx_find(handle);
|
||||
|
||||
if (sevr_idx != BLE_GATTS_INVALID_SERV_IDX &&
|
||||
s_gatts_serv_env.p_serv_info[sevr_idx].handlers.cccd_recovery_handler)
|
||||
{
|
||||
s_gatts_serv_env.p_serv_info[sevr_idx].handlers.cccd_recovery_handler(conn_idx, handle, cccd_val);
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_gatts_on_connect_cb(uint8_t conn_idx)
|
||||
{
|
||||
fpb_load_state(0);
|
||||
|
||||
for (uint8_t i = 0; i < s_gatts_serv_env.serv_num; i++)
|
||||
{
|
||||
if (s_gatts_serv_env.p_serv_info[i].handlers.on_conn_handler)
|
||||
{
|
||||
s_gatts_serv_env.p_serv_info[i].handlers.on_conn_handler(conn_idx);
|
||||
}
|
||||
}
|
||||
fpb_save_state();
|
||||
}
|
||||
|
||||
static void ble_gatts_on_disconnect_cb(uint8_t conn_idx, uint8_t reason)
|
||||
{
|
||||
for (uint8_t i = 0; i < s_gatts_serv_env.serv_num; i++)
|
||||
{
|
||||
if (s_gatts_serv_env.p_serv_info[i].handlers.on_disconn_handler)
|
||||
{
|
||||
s_gatts_serv_env.p_serv_info[i].handlers.on_disconn_handler(conn_idx, reason);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_gatts_att_perm_set(uint16_t *p_att_perm, uint16_t prop, ble_att_perm_t perm)
|
||||
{
|
||||
if (NULL == p_att_perm || 0 == prop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
*p_att_perm = 0;
|
||||
|
||||
if (prop & BLE_ATT_PROP_BROADCAST)
|
||||
{
|
||||
*p_att_perm |= (BROADCAST << 8);
|
||||
}
|
||||
|
||||
if (prop & BLE_ATT_PROP_READ)
|
||||
{
|
||||
*p_att_perm |= (READ << 8 | (((perm) & SEC_LEVEL_MASK) << READ_POS));
|
||||
}
|
||||
|
||||
if (prop & BLE_ATT_PROP_WRITE_NO_RESP)
|
||||
{
|
||||
*p_att_perm |= (WRITE_CMD << 8 | (((perm) & SEC_LEVEL_MASK) << WRITE_POS));
|
||||
}
|
||||
|
||||
if (prop & BLE_ATT_PROP_WRITE)
|
||||
{
|
||||
*p_att_perm |= (WRITE_REQ << 8 | (((perm) & SEC_LEVEL_MASK) << WRITE_POS));
|
||||
}
|
||||
|
||||
if (prop & BLE_ATT_PROP_NOTIFY)
|
||||
{
|
||||
*p_att_perm |= (NOTIFY << 8 | (((perm) & SEC_LEVEL_MASK) << NOTIFY_POS));
|
||||
}
|
||||
|
||||
if (prop & BLE_ATT_PROP_INDICATE)
|
||||
{
|
||||
*p_att_perm |= (INDICATE << 8 | (((perm) & SEC_LEVEL_MASK) << INDICATE_POS));
|
||||
}
|
||||
|
||||
if (prop & BLE_ATT_PROP_WRITE_SIGNED)
|
||||
{
|
||||
*p_att_perm |= (WRITE_SIGNED << 8 | (((perm) & SEC_LEVEL_MASK) << WRITE_POS));
|
||||
}
|
||||
|
||||
if (prop & BLE_ATT_PROP_EXTENDED)
|
||||
{
|
||||
*p_att_perm |= (EXT_PROP << 8);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
*******************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_gatts_serv_add(bool is_primary, const ble_att_uuid_t *p_uuid, uint16_t *p_handle)
|
||||
{
|
||||
size_t re_size;
|
||||
void *mal_ptr;
|
||||
uint8_t att_idx;
|
||||
|
||||
if (NULL == p_uuid)
|
||||
{
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
|
||||
// re-malloc s_p_db_info_tab
|
||||
mal_ptr = s_p_db_info_tab;
|
||||
re_size = sizeof(ble_gatts_db_info_t) * (s_create_serv_idx + 1);
|
||||
|
||||
s_p_db_info_tab = BLE_GATT_SERV_REALLOC(mal_ptr, re_size);
|
||||
BLE_GATT_REALLOC_VERIFY(s_p_db_info_tab, s_create_serv_idx, sizeof(ble_gatts_db_info_t));
|
||||
|
||||
// re-malloc s_gatts_serv_env.p_serv_info
|
||||
mal_ptr = s_gatts_serv_env.p_serv_info;
|
||||
re_size = sizeof(ble_gatts_serv_info_t) * (s_gatts_serv_env.serv_num + 1);
|
||||
|
||||
s_gatts_serv_env.p_serv_info = BLE_GATT_SERV_REALLOC(mal_ptr, re_size);
|
||||
BLE_GATT_REALLOC_VERIFY(s_gatts_serv_env.p_serv_info, s_gatts_serv_env.serv_num, sizeof(ble_gatts_serv_info_t));
|
||||
|
||||
// malloc att handle ptr table
|
||||
s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab = BLE_GATT_SERV_MALLOC(BLE_GATTS_HADNLE_PTR_SIZE);
|
||||
BLE_GATT_MALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab, BLE_GATTS_HADNLE_PTR_SIZE);
|
||||
|
||||
att_idx = s_p_db_info_tab[s_create_serv_idx].att_num;
|
||||
s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab[att_idx] = p_handle;
|
||||
|
||||
// re-malloc att table
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab = BLE_GATT_SERV_MALLOC(BLE_GATTS_ATT_ELEMENT_SIZE);
|
||||
BLE_GATT_MALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_db_tab, BLE_GATTS_ATT_ELEMENT_SIZE);
|
||||
|
||||
// record service uuid
|
||||
memcpy(&s_p_db_info_tab[s_create_serv_idx].uuid, p_uuid, sizeof(ble_att_uuid_t));
|
||||
|
||||
// ->uuid
|
||||
if (is_primary)
|
||||
{
|
||||
uint8_t uuid[16] = BLE_ATT_16_TO_128_ARRAY(BLE_ATT_DECL_PRIMARY_SERVICE);
|
||||
memcpy(s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].uuid, uuid, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t uuid[16] = BLE_ATT_16_TO_128_ARRAY(BLE_ATT_DECL_SECONDARY_SERVICE);
|
||||
memcpy(s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].uuid, uuid, 16);
|
||||
}
|
||||
// ->perm
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].perm = READ_PERM_UNSEC;
|
||||
// ->ext_perm
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].ext_perm = 0;
|
||||
// ->max_size
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].max_size = 0;
|
||||
|
||||
s_gatts_serv_env.serv_num++;
|
||||
s_p_db_info_tab[s_create_serv_idx].att_num++;
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
sdk_err_t ble_gatts_inc_serv_add(uint16_t *p_handle)
|
||||
{
|
||||
size_t re_size;
|
||||
void *mal_ptr;
|
||||
uint8_t inc_serv_idx;
|
||||
uint8_t att_idx;
|
||||
|
||||
if (NULL == p_handle)
|
||||
{
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
|
||||
att_idx = s_p_db_info_tab[s_create_serv_idx].att_num;
|
||||
|
||||
// re-malloc att handle ptr table
|
||||
mal_ptr = s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab;
|
||||
re_size = BLE_GATTS_HADNLE_PTR_SIZE * (s_p_db_info_tab[s_create_serv_idx].att_num + 1);
|
||||
|
||||
s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab = BLE_GATT_SERV_REALLOC(mal_ptr, re_size);
|
||||
BLE_GATT_REALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab, att_idx, BLE_GATTS_HADNLE_PTR_SIZE);
|
||||
|
||||
// re-malloc att table
|
||||
mal_ptr = s_p_db_info_tab[s_create_serv_idx].p_db_tab;
|
||||
re_size = BLE_GATTS_ATT_ELEMENT_SIZE * (att_idx + 1);
|
||||
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab = BLE_GATT_SERV_REALLOC(mal_ptr, re_size);
|
||||
BLE_GATT_REALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_db_tab, att_idx, BLE_GATTS_ATT_ELEMENT_SIZE);
|
||||
|
||||
// ->uuid
|
||||
uint8_t uuid[16] = BLE_ATT_16_TO_128_ARRAY(BLE_ATT_DECL_INCLUDE);
|
||||
memcpy(s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].uuid, uuid, 16);
|
||||
// ->perm
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].perm = READ_PERM_UNSEC;
|
||||
// ->ext_perm
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].ext_perm = 0;
|
||||
// ->max_size
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].max_size = 0;
|
||||
|
||||
inc_serv_idx = s_p_db_info_tab[s_create_serv_idx].inc_serv_num;
|
||||
|
||||
// re-malloc p_inc_hdl_table
|
||||
mal_ptr = s_p_db_info_tab[s_create_serv_idx].p_inc_hdl_tab;
|
||||
re_size = BLE_GATTS_HADNLE_PTR_SIZE * (s_p_db_info_tab[s_create_serv_idx].inc_serv_num + 1);
|
||||
s_p_db_info_tab[s_create_serv_idx].p_inc_hdl_tab = BLE_GATT_SERV_REALLOC(mal_ptr, re_size);
|
||||
BLE_GATT_REALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_inc_hdl_tab, inc_serv_idx, BLE_GATTS_HADNLE_PTR_SIZE);
|
||||
|
||||
s_p_db_info_tab[s_create_serv_idx].p_inc_hdl_tab = mal_ptr;
|
||||
s_p_db_info_tab[s_create_serv_idx].p_inc_hdl_tab[inc_serv_idx] = p_handle;
|
||||
s_p_db_info_tab[s_create_serv_idx].inc_serv_num++;
|
||||
|
||||
s_p_db_info_tab[s_create_serv_idx].att_num++;
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
sdk_err_t ble_gatts_characteristic_add(ble_gatts_att_t *p_att, uint16_t *p_val_handle)
|
||||
{
|
||||
size_t re_size;
|
||||
void *mal_ptr;
|
||||
uint8_t att_idx;
|
||||
|
||||
if (NULL == p_att)
|
||||
{
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
|
||||
att_idx = s_p_db_info_tab[s_create_serv_idx].att_num;
|
||||
|
||||
// re-malloc att handle ptr table
|
||||
mal_ptr = s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab;
|
||||
re_size = BLE_GATTS_HADNLE_PTR_SIZE * (s_p_db_info_tab[s_create_serv_idx].att_num + 2);
|
||||
|
||||
s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab = BLE_GATT_SERV_REALLOC(mal_ptr, re_size);
|
||||
BLE_GATT_REALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab, att_idx, BLE_GATTS_HADNLE_PTR_SIZE * 2);
|
||||
|
||||
// re-malloc att table
|
||||
mal_ptr = s_p_db_info_tab[s_create_serv_idx].p_db_tab;
|
||||
re_size = BLE_GATTS_ATT_ELEMENT_SIZE * (att_idx + 2);
|
||||
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab = BLE_GATT_SERV_REALLOC(mal_ptr, re_size);
|
||||
BLE_GATT_REALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_db_tab, att_idx, BLE_GATTS_ATT_ELEMENT_SIZE * 2);
|
||||
|
||||
// Character dec
|
||||
// ->uuid
|
||||
uint8_t uuid[16] = BLE_ATT_16_TO_128_ARRAY(BLE_ATT_DECL_CHARACTERISTIC);
|
||||
memcpy(s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].uuid, uuid, 16);
|
||||
// ->perm
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].perm = READ_PERM_UNSEC;
|
||||
// ->ext_perm
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].ext_perm = 0;
|
||||
// ->max_size
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].max_size = 0;
|
||||
|
||||
s_p_db_info_tab[s_create_serv_idx].att_num++;
|
||||
att_idx++;
|
||||
|
||||
// Character val
|
||||
// ->uuid
|
||||
if (p_att->att_uuid.type == BLE_ATT_UUID_128)
|
||||
{
|
||||
memcpy(s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].uuid, p_att->att_uuid.uuid.uuid128, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t uuid[16] = BLE_ATT_16_TO_128_ARRAY(p_att->att_uuid.uuid.uuid16);
|
||||
memcpy(s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].uuid, uuid, 16);
|
||||
}
|
||||
// ->perm
|
||||
ble_gatts_att_perm_set(&s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].perm, p_att->att_prop, p_att->att_perm);
|
||||
// ->ext_perm
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].ext_perm = ATT_VAL_LOC_USER;
|
||||
if (p_att->att_uuid.type == BLE_ATT_UUID_128)
|
||||
{
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].ext_perm |= SERVICE_TABLE_TYPE_128;
|
||||
}
|
||||
// ->max_size
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].max_size = p_att->max_len;
|
||||
|
||||
s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab[att_idx] = p_val_handle;
|
||||
|
||||
s_p_db_info_tab[s_create_serv_idx].att_num++;
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
sdk_err_t ble_gatts_descriptor_add(ble_gatts_att_t *p_att, uint16_t *p_handle)
|
||||
{
|
||||
size_t re_size;
|
||||
void *mal_ptr;
|
||||
uint8_t att_idx;
|
||||
|
||||
if (NULL == p_att)
|
||||
{
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
|
||||
att_idx = s_p_db_info_tab[s_create_serv_idx].att_num;
|
||||
|
||||
// re-malloc att handle ptr table
|
||||
mal_ptr = s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab;
|
||||
re_size = BLE_GATTS_HADNLE_PTR_SIZE * (s_p_db_info_tab[s_create_serv_idx].att_num + 1);
|
||||
|
||||
s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab = BLE_GATT_SERV_REALLOC(mal_ptr, re_size);
|
||||
BLE_GATT_REALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab, att_idx, BLE_GATTS_HADNLE_PTR_SIZE);
|
||||
|
||||
// re-malloc att table
|
||||
mal_ptr = s_p_db_info_tab[s_create_serv_idx].p_db_tab;
|
||||
re_size = BLE_GATTS_ATT_ELEMENT_SIZE * (att_idx + 1);
|
||||
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab = BLE_GATT_SERV_REALLOC(mal_ptr, re_size);
|
||||
BLE_GATT_REALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_db_tab, att_idx, BLE_GATTS_ATT_ELEMENT_SIZE);
|
||||
|
||||
// ->uuid
|
||||
if (p_att->att_uuid.type == BLE_ATT_UUID_128)
|
||||
{
|
||||
memcpy(s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].uuid, p_att->att_uuid.uuid.uuid128, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t uuid[16] = BLE_ATT_16_TO_128_ARRAY(p_att->att_uuid.uuid.uuid16);
|
||||
memcpy(s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].uuid, uuid, 16);
|
||||
}
|
||||
|
||||
// ->perm
|
||||
ble_gatts_att_perm_set(&s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].perm, p_att->att_prop, p_att->att_perm);
|
||||
// ->ext_perm
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].ext_perm = ATT_VAL_LOC_USER;
|
||||
if (p_att->att_uuid.type == BLE_ATT_UUID_128)
|
||||
{
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].ext_perm |= SERVICE_TABLE_TYPE_128;
|
||||
}
|
||||
// ->max_size
|
||||
s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].max_size = p_att->max_len;
|
||||
|
||||
s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab[att_idx] = p_handle;
|
||||
|
||||
s_p_db_info_tab[s_create_serv_idx].att_num++;
|
||||
|
||||
return SDK_SUCCESS;
|
||||
}
|
||||
|
||||
sdk_err_t ble_gatts_serv_enable(ble_gatts_handler_t *p_att_handler)
|
||||
{
|
||||
if (NULL == p_att_handler)
|
||||
{
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
|
||||
memcpy(&s_gatts_serv_env.p_serv_info[s_create_serv_idx].handlers, p_att_handler, sizeof(ble_gatts_handler_t));
|
||||
|
||||
return ble_server_prf_add(&s_prf_info);
|
||||
}
|
||||
|
||||
sdk_err_t ble_gatts_att_req_reply(uint8_t conn_idx, ble_gatts_att_req_reply_t *p_att_reply)
|
||||
{
|
||||
if (NULL == p_att_reply)
|
||||
{
|
||||
return SDK_ERR_POINTER_NULL;
|
||||
}
|
||||
|
||||
if (BLE_ATT_READ_REPLY == p_att_reply->type)
|
||||
{
|
||||
gatts_read_cfm_t cfm;
|
||||
|
||||
cfm.handle = p_att_reply->param.rd.handle;
|
||||
cfm.status = p_att_reply->param.rd.status;
|
||||
cfm.value = p_att_reply->param.rd.p_value;
|
||||
cfm.length = p_att_reply->param.rd.length;
|
||||
|
||||
return ble_gatts_read_cfm(conn_idx, &cfm);
|
||||
}
|
||||
else if (BLE_ATT_WRITE_REPLY == p_att_reply->type)
|
||||
{
|
||||
gatts_write_cfm_t cfm;
|
||||
|
||||
cfm.handle = p_att_reply->param.wr.handle;
|
||||
cfm.status = p_att_reply->param.wr.status;
|
||||
|
||||
return ble_gatts_write_cfm(conn_idx, &cfm);
|
||||
}
|
||||
else
|
||||
{
|
||||
return SDK_ERR_INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
+252
@@ -0,0 +1,252 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file ble_gatt_service.h
|
||||
*
|
||||
* @brief BLE GATT Service Module Header
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __BLE_GATT_SERVICE_H__
|
||||
#define __BLE_GATT_SERVICE_H__
|
||||
|
||||
#include "ble.h"
|
||||
#include "app_memory.h"
|
||||
|
||||
/**
|
||||
* @defgroup BLE_GATT_SERVICE_MAROC Defines
|
||||
* @{
|
||||
*/
|
||||
#define BLE_GATT_SERV_MALLOC(size) app_malloc(size) /**< Malloc adaptor. */
|
||||
#define BLE_GATT_SERV_FREE(ptr) app_free(ptr) /**< Free adaptor. */
|
||||
#define BLE_GATT_SERV_REALLOC(ptr, size) app_realloc(ptr, size) /**< Realloc adaptor. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup BLE_GATT_SERVICE_ENUM Enumerations
|
||||
* @{
|
||||
*/
|
||||
/**@brief BLE ATT UUID types. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_ATT_UUID_16, /**< 16-bit UUID type. */
|
||||
BLE_ATT_UUID_128 /**< 128-bit UUID type. */
|
||||
} ble_att_uuid_type_t;
|
||||
|
||||
/**@brief BLE ATT properties. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_ATT_PROP_BROADCAST = 0x01 << 0, /**< Broadcast. */
|
||||
BLE_ATT_PROP_READ = 0x01 << 1, /**< Read. */
|
||||
BLE_ATT_PROP_WRITE_NO_RESP = 0x01 << 2, /**< Write CMD. */
|
||||
BLE_ATT_PROP_WRITE = 0x01 << 3, /**< Write with response. */
|
||||
BLE_ATT_PROP_NOTIFY = 0x01 << 4, /**< Notify. */
|
||||
BLE_ATT_PROP_INDICATE = 0x01 << 5, /**< Indicate. */
|
||||
BLE_ATT_PROP_WRITE_SIGNED = 0x01 << 6, /**< Signed write. */
|
||||
BLE_ATT_PROP_EXTENDED = 0x01 << 7, /**< Extended. */
|
||||
} ble_att_prop_t;
|
||||
|
||||
/**@brief BLE ATT permission. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_ATT_NOAUTH, /**< No need to be encrypted or authenticated. */
|
||||
BLE_ATT_UNAUTH, /**< Need to be encrypted, but not to be authenticated. */
|
||||
BLE_ATT_AUTH, /**< Need to be encrypted and authenticated (MITM). */
|
||||
BLE_ATT_SEC_CON, /**< Need to be encrypted and authenticated (secure connections). */
|
||||
} ble_att_perm_t;
|
||||
|
||||
/**@brief BLE ATT request reply types. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_ATT_READ_REPLY, /**< GATTS read reply. */
|
||||
BLE_ATT_WRITE_REPLY /**< GATTS write reply. */
|
||||
} ble_att_req_reply_type_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup BLE_GATT_SERVICE_TYPEDEF Typedefs
|
||||
* @{
|
||||
*/
|
||||
/**@brief Read attribute value request handler. */
|
||||
typedef void (*ble_gatts_read_req_handler_t)(uint8_t conn_idx, uint16_t handle);
|
||||
|
||||
/**@brief Write attribute value request handler. */
|
||||
typedef void (*ble_gatts_write_req_handler_t)(uint8_t conn_idx, uint16_t handle, uint16_t offset, const uint8_t *p_value, uint16_t length);
|
||||
|
||||
/**@brief Notification or indication handler. */
|
||||
typedef void (*ble_gatts_ntf_ind_handler_t)(uint8_t conn_idx, uint8_t status, gatt_evt_type_t type, uint16_t h_offset);
|
||||
|
||||
/**@brief CCCD value recovery handler. */
|
||||
typedef void (*ble_gatts_cccd_recovery_handler_t)(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val);
|
||||
|
||||
/**@brief Connect handler. */
|
||||
typedef void (*ble_gatts_on_connect_handler_t)(uint8_t conn_idx);
|
||||
|
||||
/**@brief Disconnect handler. */
|
||||
typedef void (*ble_gatts_on_disconnect_handler_t)(uint8_t conn_idx, uint8_t reason);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup BLE_GATT_SERVICE_STRUCT Structures
|
||||
* @{
|
||||
*/
|
||||
/**@brief BLE ATT UUID. */
|
||||
typedef struct
|
||||
{
|
||||
ble_att_uuid_type_t type; /**< UUID type. */
|
||||
union
|
||||
{
|
||||
uint16_t uuid16; /**< 16-bit UUID. */
|
||||
uint8_t uuid128[16]; /**< 128-bit UUID. */
|
||||
}uuid; /**< UUID. */
|
||||
} ble_att_uuid_t;
|
||||
|
||||
/**@brief GATT Attribute. */
|
||||
typedef struct
|
||||
{
|
||||
ble_att_uuid_t att_uuid; /**< Pointer to the attribute UUID. */
|
||||
uint16_t att_prop; /**< ATT propertie bit map. */
|
||||
ble_att_perm_t att_perm; /**< ATT permission. */
|
||||
uint16_t max_len; /**< Maximum attribute value length. */
|
||||
} ble_gatts_att_t;
|
||||
|
||||
/**@brief GATT Attribute read/write request reply. */
|
||||
typedef struct
|
||||
{
|
||||
ble_att_req_reply_type_t type; /**< Reply type. */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint16_t handle; /**< Value handle. */
|
||||
uint8_t status; /**< Reply status. */
|
||||
}wr; /**< Write reply. */
|
||||
struct
|
||||
{
|
||||
uint16_t handle; /**< Value handle. */
|
||||
uint8_t status; /**< Reply status. */
|
||||
uint8_t *p_value; /**< Pointer to read value. */
|
||||
uint16_t length; /**< Length of read value. */
|
||||
}rd; /**< Read reply. */
|
||||
}param; /**< Parameter of reply. */
|
||||
} ble_gatts_att_req_reply_t;
|
||||
|
||||
/**@brief BLE GATTs callbacks. */
|
||||
typedef struct
|
||||
{
|
||||
ble_gatts_read_req_handler_t read_req_handler; /**< Read attribute value request handler. */
|
||||
ble_gatts_write_req_handler_t write_req_handler; /**< Write attribute value request handler. */
|
||||
ble_gatts_ntf_ind_handler_t ntf_ind_handler; /**< Notification or indication handler. */
|
||||
ble_gatts_cccd_recovery_handler_t cccd_recovery_handler; /**< CCCD value recovery handler. */
|
||||
ble_gatts_on_connect_handler_t on_conn_handler;
|
||||
ble_gatts_on_disconnect_handler_t on_disconn_handler;
|
||||
} ble_gatts_handler_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup BLE_GATT_SERVICE_FUNCTION Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Add primary/secondary service.
|
||||
*
|
||||
* @param[in] is_primary: Is primary service or not.
|
||||
* @param[in] p_uuid: Pointer to service UUID.
|
||||
* @param[out] p_handle: Pointer to service handle(will be allocated async after advertising start).
|
||||
*
|
||||
* @return Result of gatt service add.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_gatts_serv_add(bool is_primary, const ble_att_uuid_t *p_uuid, uint16_t *p_handle);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Add included service to GATT service.
|
||||
*
|
||||
* @param[in] p_offset: Pointer to the include service handle.
|
||||
*
|
||||
* @return Result of include service add.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_gatts_inc_serv_add(uint16_t *p_handle);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Add characteristic to GATT service.
|
||||
*
|
||||
* @param[in] p_att: Pointer to att info.
|
||||
* @param[out] p_handle: Pointer to value handle(will be allocated async after advertising start).
|
||||
*
|
||||
* @return Result of gatt characteristic add.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_gatts_characteristic_add(ble_gatts_att_t *p_att, uint16_t *p_val_handle);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Add descriptor to GATT service.
|
||||
*
|
||||
* @param[in] p_att: Pointer to att info.
|
||||
* @param[out] p_handle: Pointer to descriptor handle(will be allocated async after advertising start).
|
||||
*
|
||||
* @return Result of gatt descriptor add.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_gatts_descriptor_add(ble_gatts_att_t *p_att, uint16_t *p_handle);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Enable service to local DB.
|
||||
*
|
||||
* @param[in] p_att_handler: Pointer to attribute request handler.
|
||||
*
|
||||
* @return Result of publish.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_gatts_serv_enable(ble_gatts_handler_t *p_att_handler);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Reply to an attribute read/write request.
|
||||
*
|
||||
* @param[in] conn_idx: Connection index.
|
||||
* @param[in] p_att_reply: Pointer to att reply.
|
||||
*
|
||||
* @return Result of reply.
|
||||
****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_gatts_att_req_reply(uint8_t conn_idx, ble_gatts_att_req_reply_t *p_att_reply);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
kernel_module("ble_scanner") {
|
||||
sources = [ "ble_scanner.c" ]
|
||||
}
|
||||
@@ -0,0 +1,518 @@
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file ble_scanner.c
|
||||
*
|
||||
* @brief BLE Scanner Module implementation.
|
||||
*
|
||||
*****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
******************************************************************************************
|
||||
*/
|
||||
#include "ble_scanner.h"
|
||||
|
||||
#if BLE_SCANNER_ENABLE
|
||||
|
||||
/*
|
||||
* STRUCTURES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
/**@brief BLE Scanner Module environment variable. */
|
||||
struct ble_scanner_env_t
|
||||
{
|
||||
bool connect_auto;
|
||||
bool is_matched;
|
||||
ble_gap_scan_param_t scan_param;
|
||||
ble_gap_init_param_t conn_param;
|
||||
ble_scanner_evt_handler_t evt_handler;
|
||||
ble_scanner_err_handler_t err_handler;
|
||||
bool filter_enable;
|
||||
uint8_t filter_type;
|
||||
ble_scanner_filter_mode_t filter_mode;
|
||||
ble_scanner_filter_data_t target_data;
|
||||
};
|
||||
|
||||
/*
|
||||
* LOCAL VARIABLE DECLARATION
|
||||
*****************************************************************************************
|
||||
*/
|
||||
static struct ble_scanner_env_t s_scanner_env;
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
//static void on_scanner_stoped(void *arg)
|
||||
static void on_scanner_stoped(const ble_gap_stopped_reason_t reason)
|
||||
{
|
||||
ble_scanner_evt_t event;
|
||||
uint8_t error_code;
|
||||
|
||||
event.evt_type = BLE_SCANNER_EVT_INVALID;
|
||||
|
||||
if (BLE_GAP_STOPPED_REASON_TIMEOUT == reason)
|
||||
{
|
||||
event.evt_type = s_scanner_env.filter_type ? BLE_SCANNER_EVT_FILTER_NO_MATCH : BLE_SCANNER_EVT_TIMEOUT;
|
||||
}
|
||||
|
||||
if (BLE_GAP_STOPPED_REASON_ON_USER == reason && s_scanner_env.is_matched)
|
||||
{
|
||||
s_scanner_env.is_matched = false;
|
||||
error_code = ble_gap_connect(BLE_GAP_OWN_ADDR_STATIC, &s_scanner_env.conn_param);
|
||||
if (error_code)
|
||||
{
|
||||
ble_scanner_err_on_ble_capture(error_code);
|
||||
}
|
||||
}
|
||||
|
||||
if (event.evt_type && s_scanner_env.evt_handler)
|
||||
{
|
||||
s_scanner_env.evt_handler(&event);
|
||||
}
|
||||
}
|
||||
|
||||
static void on_scanner_connected(uint8_t conn_idx)
|
||||
{
|
||||
ble_scanner_evt_t event;
|
||||
|
||||
event.evt_type = BLE_SCANNER_EVT_CONNECTED;
|
||||
event.param.conn_idx = conn_idx;
|
||||
|
||||
if (s_scanner_env.evt_handler)
|
||||
{
|
||||
s_scanner_env.evt_handler(&event);
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_scanner_uuid_encode(const uint8_t *p_uuid_data, uint16_t length, uint8_t uuid_type, ble_scanner_uuid_t *p_uuid_buff)
|
||||
{
|
||||
if (NULL == p_uuid_data || NULL == p_uuid_buff)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t current_offset = 0;
|
||||
|
||||
while (current_offset < length)
|
||||
{
|
||||
switch (uuid_type)
|
||||
{
|
||||
case UUID_16_BIT_BYTES:
|
||||
if (p_uuid_buff->uuid_16_bit_count < UUID_16_BIT_NUM_MAX)
|
||||
{
|
||||
memcpy(&p_uuid_buff->uuid_16_bit[p_uuid_buff->uuid_16_bit_count++], &p_uuid_data[current_offset], UUID_16_BIT_BYTES);
|
||||
current_offset += UUID_16_BIT_BYTES;
|
||||
}
|
||||
break;
|
||||
|
||||
case UUID_32_BIT_BYTES:
|
||||
if (p_uuid_buff->uuid_32_bit_count < UUID_32_BIT_NUM_MAX)
|
||||
{
|
||||
memcpy(&p_uuid_buff->uuid_16_bit[p_uuid_buff->uuid_32_bit_count++], &p_uuid_data[current_offset], UUID_32_BIT_BYTES);
|
||||
current_offset += UUID_32_BIT_BYTES;
|
||||
}
|
||||
break;
|
||||
|
||||
case UUID_128_BIT_BYTES:
|
||||
if (p_uuid_buff->uuid_128_bit_count < UUID_128_BIT_NUM_MAX)
|
||||
{
|
||||
memcpy(&p_uuid_buff->uuid_128_bit[p_uuid_buff->uuid_128_bit_count++][0], &p_uuid_data[current_offset], UUID_128_BIT_BYTES);
|
||||
current_offset += UUID_128_BIT_BYTES;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_scanner_parse_record(uint8_t ad_type, const uint8_t *p_data, uint16_t length, ble_scanner_parse_rec_t *p_parse_rec)
|
||||
{
|
||||
uint8_t rec_idx = p_parse_rec->type_count;
|
||||
|
||||
p_parse_rec->single_rec[rec_idx].ad_type = ad_type;
|
||||
p_parse_rec->single_rec[rec_idx].type_data.p_data = p_data;
|
||||
p_parse_rec->single_rec[rec_idx].type_data.length = length;
|
||||
p_parse_rec->type_count++;
|
||||
}
|
||||
|
||||
static void ble_scanner_data_parse(const ble_gap_evt_adv_report_t *p_adv_report, ble_scanner_parse_report_t *p_parse_report)
|
||||
{
|
||||
if (NULL == p_adv_report || NULL == p_parse_report)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
memset(p_parse_report, 0, sizeof(ble_scanner_parse_report_t));
|
||||
|
||||
p_parse_report->adv_report_type = (ble_gap_adv_report_type_t)p_adv_report->adv_type;
|
||||
p_parse_report->rssi = p_adv_report->rssi;
|
||||
memcpy(&p_parse_report->peer_addr, &p_adv_report->broadcaster_addr, sizeof(ble_gap_bdaddr_t));
|
||||
memcpy(&s_scanner_env.conn_param.peer_addr, &p_adv_report->broadcaster_addr, sizeof(ble_gap_bdaddr_t));
|
||||
|
||||
uint8_t parse_offset = 0;
|
||||
uint8_t *adv_data = p_adv_report->data;
|
||||
uint8_t adv_data_len = p_adv_report->length;
|
||||
uint8_t fragment_ad_type = 0;
|
||||
uint8_t fragment_length = 0;
|
||||
uint8_t data_length = 0;
|
||||
|
||||
while (parse_offset < adv_data_len)
|
||||
{
|
||||
fragment_length = adv_data[parse_offset++];
|
||||
|
||||
if (0 == fragment_length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
data_length = fragment_length - 1;
|
||||
fragment_ad_type = adv_data[parse_offset++];
|
||||
|
||||
switch (fragment_ad_type)
|
||||
{
|
||||
case BLE_GAP_AD_TYPE_FLAGS:
|
||||
p_parse_report->flag = adv_data[parse_offset];
|
||||
p_parse_report->adv_type_parsed.flag = true;
|
||||
break;
|
||||
|
||||
case BLE_GAP_AD_TYPE_APPEARANCE:
|
||||
p_parse_report->appearance = adv_data[parse_offset] | adv_data[parse_offset + 1] << 8;
|
||||
p_parse_report->adv_type_parsed.appearance = true;
|
||||
break;
|
||||
|
||||
case BLE_GAP_AD_TYPE_SHORTENED_NAME:
|
||||
case BLE_GAP_AD_TYPE_COMPLETE_NAME:
|
||||
p_parse_report->local_name.p_data = &adv_data[parse_offset];
|
||||
p_parse_report->local_name.length = data_length;
|
||||
p_parse_report->adv_type_parsed.local_name = true;
|
||||
break;
|
||||
|
||||
case BLE_GAP_AD_TYPE_MANU_SPECIFIC_DATA:
|
||||
p_parse_report->manufacture_data.p_data = &adv_data[parse_offset];
|
||||
p_parse_report->manufacture_data.length = data_length;
|
||||
p_parse_report->adv_type_parsed.manufacture_data = true;
|
||||
break;
|
||||
|
||||
case BLE_GAP_AD_TYPE_MORE_16_BIT_UUID:
|
||||
case BLE_GAP_AD_TYPE_COMPLETE_LIST_16_BIT_UUID:
|
||||
ble_scanner_uuid_encode(&adv_data[parse_offset], data_length, UUID_16_BIT_BYTES, &p_parse_report->uuid_list);
|
||||
p_parse_report->adv_type_parsed.uuid = true;
|
||||
break;
|
||||
|
||||
case BLE_GAP_AD_TYPE_MORE_32_BIT_UUID:
|
||||
case BLE_GAP_AD_TYPE_COMPLETE_LIST_32_BIT_UUID:
|
||||
ble_scanner_uuid_encode(&adv_data[parse_offset], data_length, UUID_32_BIT_BYTES, &p_parse_report->uuid_list);
|
||||
p_parse_report->adv_type_parsed.uuid = true;
|
||||
break;
|
||||
|
||||
case BLE_GAP_AD_TYPE_MORE_128_BIT_UUID:
|
||||
case BLE_GAP_AD_TYPE_COMPLETE_LIST_128_BIT_UUID:
|
||||
ble_scanner_uuid_encode(&adv_data[parse_offset], data_length, UUID_128_BIT_BYTES, &p_parse_report->uuid_list);
|
||||
p_parse_report->adv_type_parsed.uuid = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
ble_scanner_parse_record(fragment_ad_type, &adv_data[parse_offset], data_length, &p_parse_report->other_parse_rec);
|
||||
break;
|
||||
}
|
||||
|
||||
parse_offset += data_length;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ble_scanner_filter_uuid_macth(ble_data_t *p_uuid, ble_scanner_uuid_t *p_uuid_list)
|
||||
{
|
||||
if (p_uuid->length == UUID_16_BIT_BYTES)
|
||||
{
|
||||
for (uint8_t i = 0; i < p_uuid_list->uuid_16_bit_count; i++)
|
||||
{
|
||||
if (0 == memcmp(p_uuid->p_data, (uint8_t *)&p_uuid_list->uuid_16_bit[i], UUID_16_BIT_BYTES))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_uuid->length == UUID_32_BIT_BYTES)
|
||||
{
|
||||
for (uint8_t i = 0; i < p_uuid_list->uuid_32_bit_count; i++)
|
||||
{
|
||||
if (0 == memcmp(p_uuid->p_data, (uint8_t *)&p_uuid_list->uuid_32_bit[i], UUID_32_BIT_BYTES))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_uuid->length == UUID_128_BIT_BYTES)
|
||||
{
|
||||
for (uint8_t i = 0; i < p_uuid_list->uuid_128_bit_count; i++)
|
||||
{
|
||||
if (0 == memcmp(p_uuid->p_data, p_uuid_list->uuid_128_bit[i], UUID_128_BIT_BYTES))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ble_scanner_filter_match_check(ble_scanner_parse_report_t *p_parse_report, ble_scanner_filter_match_t *p_match_result)
|
||||
{
|
||||
memset(p_match_result, 0, sizeof(ble_scanner_filter_match_t));
|
||||
|
||||
if (s_scanner_env.filter_type & BLE_SCANNER_NAME_FILTER)
|
||||
{
|
||||
if (p_parse_report->local_name.length == s_scanner_env.target_data.dev_name.length &&
|
||||
0 == memcmp(p_parse_report->local_name.p_data,
|
||||
s_scanner_env.target_data.dev_name.p_data,
|
||||
s_scanner_env.target_data.dev_name.length))
|
||||
{
|
||||
p_match_result->dev_name_match = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (s_scanner_env.filter_type & BLE_SCANNER_APPEARANCE_FILTER)
|
||||
{
|
||||
if (p_parse_report->appearance == s_scanner_env.target_data.appearance)
|
||||
{
|
||||
p_match_result->appearance_match = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (s_scanner_env.filter_type & BLE_SCANNER_UUID_FILTER)
|
||||
{
|
||||
if (ble_scanner_filter_uuid_macth(&s_scanner_env.target_data.svr_uuid, &p_parse_report->uuid_list))
|
||||
{
|
||||
p_match_result->uuid_match = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (s_scanner_env.filter_type & BLE_SCANNER_ADDR_FILTER)
|
||||
{
|
||||
if (0 == memcmp(&s_scanner_env.target_data.target_addr, &p_parse_report->peer_addr, sizeof(ble_gap_bdaddr_t)))
|
||||
{
|
||||
p_match_result->addr_match = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (BLE_SCANNER_FILTER_ANYONE_MATCH == s_scanner_env.filter_mode)
|
||||
{
|
||||
if (p_match_result->dev_name_match ||
|
||||
p_match_result->appearance_match ||
|
||||
p_match_result->uuid_match ||
|
||||
p_match_result->addr_match)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s_scanner_env.filter_type & BLE_SCANNER_NAME_FILTER && !p_match_result->dev_name_match)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s_scanner_env.filter_type & BLE_SCANNER_APPEARANCE_FILTER && !p_match_result->appearance_match)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s_scanner_env.filter_type & BLE_SCANNER_UUID_FILTER && !p_match_result->uuid_match)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s_scanner_env.filter_type & BLE_SCANNER_ADDR_FILTER && !p_match_result->addr_match)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void on_scanner_adv_report(const ble_gap_evt_adv_report_t *p_adv_report)
|
||||
{
|
||||
ble_scanner_parse_report_t parse_report;
|
||||
ble_scanner_evt_t event;
|
||||
ble_scanner_filter_match_t match_result;
|
||||
|
||||
memset(&event, 0, sizeof(event));
|
||||
memset(&parse_report, 0, sizeof(parse_report));
|
||||
memset(&match_result, 0, sizeof(match_result));
|
||||
|
||||
if(!s_scanner_env.is_matched)
|
||||
{
|
||||
ble_scanner_data_parse(p_adv_report, &parse_report);
|
||||
}
|
||||
|
||||
event.evt_type = BLE_SCANNER_EVT_ADV_REPORT_PARSE;
|
||||
memcpy(&event.param.parse_record, &parse_report, sizeof(ble_scanner_parse_report_t));
|
||||
|
||||
if (s_scanner_env.evt_handler)
|
||||
{
|
||||
s_scanner_env.evt_handler(&event);
|
||||
}
|
||||
|
||||
if (s_scanner_env.filter_enable)
|
||||
{
|
||||
if (ble_scanner_filter_match_check(&parse_report, &match_result))
|
||||
{
|
||||
event.evt_type = BLE_SCANNER_EVT_FILTER_MATCH;
|
||||
memcpy(&event.param.match_result, &match_result, sizeof(ble_scanner_filter_match_t));
|
||||
|
||||
if (s_scanner_env.evt_handler)
|
||||
{
|
||||
s_scanner_env.evt_handler(&event);
|
||||
}
|
||||
|
||||
if (s_scanner_env.connect_auto)
|
||||
{
|
||||
s_scanner_env.is_matched = true;
|
||||
ble_scanner_stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GLOBAL FUNCTION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_scanner_init(ble_scanner_init_t *p_scan_init)
|
||||
{
|
||||
if (NULL == p_scan_init)
|
||||
{
|
||||
return SDK_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
memcpy(&s_scanner_env, p_scan_init, sizeof(ble_scanner_init_t));
|
||||
|
||||
return ble_gap_scan_param_set(BLE_GAP_OWN_ADDR_STATIC, &s_scanner_env.scan_param);
|
||||
}
|
||||
|
||||
sdk_err_t ble_scanner_filter_set(uint8_t filter_type, ble_scanner_filter_data_t *p_filter_data)
|
||||
{
|
||||
sdk_err_t error_code = SDK_SUCCESS;
|
||||
|
||||
if (NULL == p_filter_data)
|
||||
{
|
||||
return SDK_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
s_scanner_env.filter_type = filter_type;
|
||||
memcpy(&s_scanner_env.target_data, p_filter_data, sizeof(ble_scanner_filter_data_t));
|
||||
|
||||
return error_code;
|
||||
}
|
||||
|
||||
void ble_scanner_filter_disable(void)
|
||||
{
|
||||
s_scanner_env.filter_enable = false;
|
||||
}
|
||||
|
||||
void ble_scanner_filter_enable(ble_scanner_filter_mode_t filter_mode)
|
||||
{
|
||||
s_scanner_env.filter_mode = filter_mode;
|
||||
|
||||
s_scanner_env.filter_enable = true;
|
||||
}
|
||||
|
||||
sdk_err_t ble_scanner_start(void)
|
||||
{
|
||||
ble_scanner_evt_t event;
|
||||
|
||||
if (s_scanner_env.scan_param.use_whitelist)
|
||||
{
|
||||
event.evt_type = BLE_SCANNER_EVT_WHITELIST_REQUEST;
|
||||
|
||||
if (s_scanner_env.evt_handler)
|
||||
{
|
||||
s_scanner_env.evt_handler(&event);
|
||||
}
|
||||
}
|
||||
|
||||
return ble_gap_scan_start();
|
||||
}
|
||||
|
||||
sdk_err_t ble_scanner_stop(void)
|
||||
{
|
||||
return ble_gap_scan_stop();
|
||||
}
|
||||
|
||||
|
||||
void ble_scanner_err_on_ble_capture(uint8_t err_code)
|
||||
{
|
||||
if (s_scanner_env.err_handler && err_code)
|
||||
{
|
||||
s_scanner_env.err_handler(err_code);
|
||||
}
|
||||
}
|
||||
|
||||
void ble_scanner_evt_on_ble_capture(const ble_evt_t *p_evt)
|
||||
{
|
||||
if (NULL == p_evt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (p_evt->evt_id)
|
||||
{
|
||||
case BLE_GAPM_EVT_SCAN_START:
|
||||
break;
|
||||
|
||||
case BLE_GAPM_EVT_SCAN_STOP:
|
||||
on_scanner_stoped(p_evt->evt.gapm_evt.params.scan_stop.reason);
|
||||
break;
|
||||
|
||||
case BLE_GAPM_EVT_ADV_REPORT:
|
||||
on_scanner_adv_report(&p_evt->evt.gapm_evt.params.adv_report);
|
||||
break;
|
||||
|
||||
case BLE_GAPC_EVT_CONNECTED:
|
||||
on_scanner_connected(p_evt->evt.gapc_evt.index);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,331 @@
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file ble_scanner.h
|
||||
*
|
||||
* @brief BLE Scanner Module API
|
||||
*
|
||||
*****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __BLE_SCANNER__
|
||||
#define __BLE_SCANNER__
|
||||
|
||||
#include "ble_module_config.h"
|
||||
#include "ble_event.h"
|
||||
#include "ble_gapm.h"
|
||||
|
||||
/**
|
||||
* @defgroup BLE_SCANNER_MAROC Defines
|
||||
* @{
|
||||
*/
|
||||
/**@brief Capture scanner event. */
|
||||
#define BLE_SCANNER_EVT_CAPTURE(err, evt_id, arg) \
|
||||
do \
|
||||
{ \
|
||||
if (err != BLE_SUCCESS) \
|
||||
{ \
|
||||
ble_scanner_err_on_ble_capture(err); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ble_scanner_evt_on_ble_capture(evt_id, arg); \
|
||||
} \
|
||||
} while(0)
|
||||
/** @} */
|
||||
|
||||
#define AD_TYPE_NUM_MAX 10 /**< Maximum number of ad type can be parsed in one advertising report packet. */
|
||||
#define UUID_16_BIT_NUM_MAX 14 /**< Maximum number of 16 bit uuid service can be parsed in one advertising report packet. */
|
||||
#define UUID_32_BIT_NUM_MAX 7 /**< Maximum number of 32 bit uuid service can be parsed in one advertising report packet. */
|
||||
#define UUID_128_BIT_NUM_MAX 1 /**< Maximum number of 128 bit uuid service can be parsed in one advertising report packet. */
|
||||
|
||||
#define UUID_16_BIT_BYTES 2 /**< Length of bytes for 16 bit UUID. */
|
||||
#define UUID_32_BIT_BYTES 4 /**< Length of bytes for 32 bit UUID. */
|
||||
#define UUID_128_BIT_BYTES 16 /**< Length of bytes for 128 bit UUID. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup BLE_SCANNER_ENUM Enumerations
|
||||
* @{
|
||||
*/
|
||||
/**@brief BLE GAP event ids. */
|
||||
enum
|
||||
{
|
||||
BLE_GAP_EVT_ID_ADV_START = BLE_COMMON_EVT_BASE,
|
||||
BLE_GAP_EVT_ID_ADV_STOP,
|
||||
BLE_GAP_EVT_ID_ADV_REPORT,
|
||||
BLE_GAP_EVT_ID_CONNECTED,
|
||||
BLE_GAP_EVT_ID_DISCONNECTED,
|
||||
BLE_GAP_EVT_ID_CONNECTED_CANCLE,
|
||||
BLE_GAP_EVT_ID_CONN_PARAM_UPDATED,
|
||||
BLE_GAP_EVT_ID_PHY_UPDATED,
|
||||
BLE_GAP_EVT_ID_DEV_INFO_GOT,
|
||||
BLE_GAP_EVT_ID_SCAN_START,
|
||||
BLE_GAP_EVT_ID_SCAN_STOP,
|
||||
BLE_GAP_EVT_ID_SCAN_REQUEST,
|
||||
BLE_GAP_EVT_ID_SYNC_ESTABLISH,
|
||||
BLE_GAP_EVT_ID_PEER_NAME_GOT,
|
||||
BLE_GAP_EVT_ID_CONN_PARAM_UPDATE_REQUEST,
|
||||
BLE_GAP_EVT_ID_CONN_INFO_GOT,
|
||||
BLE_GAP_EVT_ID_PEER_DEV_INFO_GOT,
|
||||
BLE_GAP_EVT_ID_DATA_LENGTH_UPDATED,
|
||||
BLE_GAP_EVT_ID_READ_RSLV_ADDR
|
||||
};
|
||||
|
||||
/**@brief BLE Scanner filter match mode. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_SCANNER_FILTER_ALL_MATCH, /**< Only when all type match. */
|
||||
BLE_SCANNER_FILTER_ANYONE_MATCH, /**< Just match any type . */
|
||||
} ble_scanner_filter_mode_t;
|
||||
|
||||
/**@brief BLE Scanner filter types. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_SCANNER_NAME_FILTER = (0x01 << 0), /**< Filter device base on target device name. */
|
||||
BLE_SCANNER_APPEARANCE_FILTER = (0x01 << 1), /**< Filter device base on target appearance. */
|
||||
BLE_SCANNER_UUID_FILTER = (0x01 << 2), /**< Filter device base on tagert service UUID. */
|
||||
BLE_SCANNER_ADDR_FILTER = (0x01 << 3), /**< Filter device base on target address. */
|
||||
} ble_scanner_filter_type_t;
|
||||
|
||||
/**@brief BLE Scanner event type. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_SCANNER_EVT_INVALID, /**< Invalid event. */
|
||||
BLE_SCANNER_EVT_WHITELIST_REQUEST, /**< Request user to add whitelist. */
|
||||
BLE_SCANNER_EVT_TIMEOUT, /**< Scan tiemout. */
|
||||
BLE_SCANNER_EVT_ADV_REPORT_PARSE, /**< Advertising report parsed. */
|
||||
BLE_SCANNER_EVT_FILTER_MATCH, /**< Filter match from adv report. */
|
||||
BLE_SCANNER_EVT_FILTER_NO_MATCH, /**< Filter no match from adv report. */
|
||||
BLE_SCANNER_EVT_CONNECTED, /**< Connected. */
|
||||
} ble_scanner_evt_type_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup BLE_SCANNER_STRUCT Structures
|
||||
* @{
|
||||
*/
|
||||
/**@brief Data structure. */
|
||||
typedef struct
|
||||
{
|
||||
const uint8_t *p_data; /**< Pointer to the data. */
|
||||
uint16_t length; /**< Length of the data. */
|
||||
} ble_data_t;
|
||||
|
||||
/**@brief Target data provided to filter. */
|
||||
typedef struct
|
||||
{
|
||||
ble_data_t dev_name; /**< Target device name. */
|
||||
uint16_t appearance; /**< Target appearance. */
|
||||
ble_data_t svr_uuid; /**< Target service UUID. */
|
||||
ble_gap_bdaddr_t target_addr; /**< Target device address. */
|
||||
} ble_scanner_filter_data_t;
|
||||
|
||||
/**@brief UUID data parsed from advertising report. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t uuid_16_bit_count; /**< Count of 16 bit uuid parsed. */
|
||||
uint8_t uuid_32_bit_count; /**< Count of 32 bit uuid parsed. */
|
||||
uint8_t uuid_128_bit_count; /**< Count of 128 bit uuid parsed. */
|
||||
uint16_t uuid_16_bit[UUID_16_BIT_NUM_MAX]; /**< All 16 bit uuid data parsed. */
|
||||
uint32_t uuid_32_bit[UUID_32_BIT_NUM_MAX]; /**< All 32 bit uuid data parsed. */
|
||||
uint8_t uuid_128_bit[UUID_128_BIT_NUM_MAX][UUID_128_BIT_BYTES]; /**< All 128 bit uuid data parsed. */
|
||||
} ble_scanner_uuid_t;
|
||||
|
||||
/**@brief Parsed adv types */
|
||||
typedef struct
|
||||
{
|
||||
bool flag; /**< True if flag existed, false or not. */
|
||||
bool appearance; /**< True if appearance existed, false or not. */
|
||||
bool local_name; /**< True if service UUID existed, false or not. */
|
||||
bool manufacture_data; /**< True if manufacture data existed, false or not. */
|
||||
bool uuid; /**< True if UUID existed, false or not. */
|
||||
} ble_scanner_adv_type_t;
|
||||
|
||||
/**@brief Single advertising type parsed from advertising report. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ad_type; /**< GAP advertising data type. */
|
||||
ble_data_t type_data; /**< Adv type raw data. */
|
||||
} ble_scanner_single_rec_t;
|
||||
|
||||
/**@brief All GAP advertising type parsed from advertising report. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t type_count; /**< Count of advertising type parsed. */
|
||||
ble_scanner_single_rec_t single_rec[AD_TYPE_NUM_MAX]; /**< Information of parsed. */
|
||||
} ble_scanner_parse_rec_t;
|
||||
|
||||
/**@brief All parsed result from advertising report. */
|
||||
typedef struct
|
||||
{
|
||||
ble_gap_adv_report_type_t adv_report_type; /**< Advertising report type. */
|
||||
ble_scanner_adv_type_t adv_type_parsed; /**< Parsed adv types. */
|
||||
ble_gap_bdaddr_t peer_addr; /**< Address of device from which advertising. */
|
||||
int8_t rssi; /**< RSSI (between -127 and +20 dBm). */
|
||||
uint8_t flag; /**< Flag, shall not appear more than once in a block. */
|
||||
uint16_t appearance; /**< Appearance, shall not appear more than once in a block. */
|
||||
ble_data_t local_name; /**< Local name, shall not appear more than once in a block. */
|
||||
ble_data_t manufacture_data; /**< Manufacturer specific data. */
|
||||
ble_scanner_uuid_t uuid_list; /**< Service uuid list. */
|
||||
ble_scanner_parse_rec_t other_parse_rec; /**< Other data parse record. */
|
||||
} ble_scanner_parse_report_t;
|
||||
|
||||
/**@brief Matched with which target data. */
|
||||
typedef struct
|
||||
{
|
||||
bool dev_name_match; /**< True if device name matched, false or not. */
|
||||
bool appearance_match; /**< True if appearance matched, false or not. */
|
||||
bool uuid_match; /**< True if service UUID matched, false or not. */
|
||||
bool addr_match; /**< True if address matched, false or not. */
|
||||
} ble_scanner_filter_match_t;
|
||||
|
||||
/**@brief BLE Scanner Module event. */
|
||||
typedef struct
|
||||
{
|
||||
ble_scanner_evt_type_t evt_type; /**< BLE Scanner event type. */
|
||||
union
|
||||
{
|
||||
ble_scanner_filter_match_t match_result; /**< Filter match result. */
|
||||
ble_scanner_parse_report_t parse_record; /**< Advertising report parse result record. */
|
||||
uint8_t conn_idx; /**< Connect index. */
|
||||
} param;
|
||||
} ble_scanner_evt_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup BLE_SCANNER_TYPEDEF Typedefs
|
||||
* @{
|
||||
*/
|
||||
/**@brief BLE scanner event handler type. */
|
||||
typedef void (*ble_scanner_evt_handler_t)(ble_scanner_evt_t *p_evt);
|
||||
|
||||
/**@brief BLE scanner error handler type. */
|
||||
typedef void (*ble_scanner_err_handler_t)(uint8_t err_code);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup BLE_SCANNER_STRUCT Structures
|
||||
* @{
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
bool connect_auto; /**< Ture: Connect to target device when found, False: Notify to application when device when found. */
|
||||
ble_gap_scan_param_t scan_param; /**< Scan parameters. */
|
||||
ble_gap_init_param_t conn_param; /**< Connect parameters which must be initialized when @see connect_auto to be set Ture. */
|
||||
ble_scanner_evt_handler_t evt_handler; /**< Handler to handle scan events for application. */
|
||||
ble_scanner_err_handler_t err_handler; /**< Handler to handle scan errors for application. */
|
||||
} ble_scanner_init_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup BLE_SCANNER_FUNCTION Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief BLE Scanner Module initialization.
|
||||
*
|
||||
* @param[in] p_scanner_init: Pointer to BLE Scanner Module initialization parameters
|
||||
*
|
||||
* @return Result of init operation.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_scanner_init(ble_scanner_init_t *p_scanner_init);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief BLE Scanner Module filter set(can override set).
|
||||
*
|
||||
* @param[in] filter_type: Filter type.
|
||||
* @param[in] p_filter_data: Pointer to data for filtering.
|
||||
*
|
||||
* @return Result of set operation.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_scanner_filter_set(uint8_t filter_type, ble_scanner_filter_data_t *p_filter_data);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief BLE Scanner Module filter diasble.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void ble_scanner_filter_disable(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief BLE Scan Module filter enable.
|
||||
*
|
||||
* @param[in] filter_mode: Filter mode.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void ble_scanner_filter_enable(ble_scanner_filter_mode_t filter_mode);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief BLE Scanner Module starts scanning device.
|
||||
*
|
||||
* @return Result of start scanning.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_scanner_start(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief BLE Scanner Module stop scanning device.
|
||||
*
|
||||
* @return Result of stop scanning.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
sdk_err_t ble_scanner_stop(void);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Capture scanner events on BLE.
|
||||
*
|
||||
* @param[in] evt_id: Event ID on BLE.
|
||||
* @param[in] arg: Arguments.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void ble_scanner_evt_on_ble_capture(const ble_evt_t *p_evt);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Capture scanner error.
|
||||
*
|
||||
* @param[in] err_code: Error code.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void ble_scanner_err_on_ble_capture(uint8_t err_code);
|
||||
/** @} */
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
kernel_module("ble_time") {
|
||||
sources = [ "ble_time.c" ]
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file ble_time.c
|
||||
*
|
||||
* @brief Provide method to get and calculate ble time.
|
||||
*
|
||||
*****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2019 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#include "grx_hal.h"
|
||||
#include "grx_sys.h"
|
||||
#include "ble_time.h"
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief This function get the ble time.
|
||||
*
|
||||
* @note This function is supported only when ble core is powered on
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
ble_time_t rwip_time_get(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief This function gets the ble time.
|
||||
*
|
||||
* @note This function is supported only when ble stack is initiated
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
SECTION_RAM_CODE ble_time_t ble_time_get(void)
|
||||
{
|
||||
pwr_mgmt_ble_wakeup();
|
||||
return rwip_time_get();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef __APP_BLE_TIME_H__
|
||||
#define __APP_BLE_TIME_H__
|
||||
#include "grx_hal.h"
|
||||
|
||||
/*
|
||||
* MACRO DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
#define TICK_MS_IN_HUS (2000)
|
||||
#define HALF_SLOT_SIZE (625)
|
||||
#define RWIP_MAX_CLOCK_TIME (0xFFFFFFF)
|
||||
#define SECOND_IN_HUS (2000000)
|
||||
#define CLK_SUB(clock_a, clock_b) ((uint32_t)(((clock_a) - (clock_b)) & RWIP_MAX_CLOCK_TIME))
|
||||
|
||||
/*
|
||||
* STRUCTURE DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t hs;
|
||||
uint16_t hus;
|
||||
} ble_time_t;
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief This function get the ble time.
|
||||
*
|
||||
* @note This function is supported only when ble stack is initiated
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
ble_time_t ble_time_get(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
# Copyright (c) 2024 GOODIX.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "inc" ]
|
||||
}
|
||||
|
||||
kernel_module("crypto_lib") {
|
||||
sources = [
|
||||
"src/crypto_aes.c",
|
||||
"src/crypto_ecc.c",
|
||||
"src/crypto_ecc_port.c",
|
||||
"src/crypto_gcm.c",
|
||||
"src/crypto_pkc.c",
|
||||
"src/crypto_pkc_port.c",
|
||||
"src/crypto_rsa.c",
|
||||
"src/crypto_rsa_port.c",
|
||||
"src/crypto_sha256.c",
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,360 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file crypto_aes.h
|
||||
* @author BLE Driver Team
|
||||
* @brief Header file containing functions prototypes of crypto AES library.
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2022 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup PERIPHERAL Peripheral Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CRYPTO_DRIVER CRYPTO DRIVER
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup CRYPTO_AES AES
|
||||
* @brief AES CRYPTO driver.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __CRYPTO_AES_H__
|
||||
#define __CRYPTO_AES_H__
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/** @defgroup CRYPTO_AES_MACRO Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define AES_BLOCK_SIZE 16 /**< AES BLOCK SIZE. */
|
||||
#define AES_ENCRYPT 1 /**< AES ENCRYPT MODE. */
|
||||
#define AES_DECRYPT 0 /**< AES DECRYPT MODE. */
|
||||
#define AES_MAX_KEY_SIZE 32 /**< AES MAX KEY SIZE. */
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup CRYPTO_AES_ENUM Enumerations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This defines the process state of aes padding type value.
|
||||
*/
|
||||
typedef enum {
|
||||
PADDING_NONE = 0, /**< AES padding type none. */
|
||||
PADDING_ZEROS, /**< AES padding type zeros. */
|
||||
PADDING_PKCS7, /**< AES padding type pkcs7. */
|
||||
} crypto_aes_padding_t;
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup CRYPTO_AES_CONTEXT_STRUCTURES Structures
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup AES Context Structurs Definition
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This defines the structure of aes context.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t key[AES_MAX_KEY_SIZE]; /**< the key. */
|
||||
uint16_t keybits; /**< the keybits. */
|
||||
crypto_aes_padding_t padding_mode; /**< padding mode. */
|
||||
void *instance; /**< the aes instance. */
|
||||
} crypto_aes_context;
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup CRYPTO_AES_FUNCTIONS Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief crypto aes init.
|
||||
*
|
||||
* @param[in] ctx: aes context.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void crypto_aes_init(crypto_aes_context *ctx);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief crypto aes free.
|
||||
*
|
||||
* @param[in] ctx: aes context.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void crypto_aes_free(crypto_aes_context *ctx);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief crypto aes set the padding type.
|
||||
*
|
||||
* @param[in] ctx: aes context.
|
||||
* @param[in] padding_type: PADDING_NONE/PADDING_ZEROS/PADDING_PKCS7.
|
||||
*
|
||||
* @retval ::-1: The aes set paddings type error.
|
||||
* @retval ::0: The aes set paddings type successfully.
|
||||
****************************************************************************************
|
||||
*/
|
||||
int crypto_aes_set_paddings(crypto_aes_context *ctx, crypto_aes_padding_t padding_type);
|
||||
|
||||
/**
|
||||
* ****************************************************************************************
|
||||
* @brief AES key schedule (encryption)
|
||||
*
|
||||
* @param[in] ctx: AES context to be initialized
|
||||
* @param[in] key: encryption key
|
||||
* @param[in] keybits: must be 128, 192 or 256
|
||||
*
|
||||
* @retval ::-1: The aes set key enc error.
|
||||
* @retval ::0: The aes set key enc successfully.
|
||||
* ****************************************************************************************
|
||||
*/
|
||||
int crypto_aes_setkey_enc(crypto_aes_context *ctx, uint8_t *key, uint16_t keybits);
|
||||
|
||||
/**
|
||||
* ****************************************************************************************
|
||||
* @brief AES key schedule (decryption)
|
||||
*
|
||||
* @param[in] ctx: AES context to be initialized
|
||||
* @param[in] key: encryption key
|
||||
* @param[in] keybits: must be 128, 192 or 256
|
||||
*
|
||||
* @retval ::-1: The aes set key enc error.
|
||||
* @retval ::0: The aes set key enc successfully.
|
||||
* ****************************************************************************************
|
||||
*/
|
||||
int crypto_aes_setkey_dec(crypto_aes_context *ctx, uint8_t *key, uint16_t keybits);
|
||||
|
||||
/**
|
||||
* ****************************************************************************************
|
||||
* @brief pkcs7 padding algorithm
|
||||
*
|
||||
* @param[in] input: input block
|
||||
* @param[in] length: input length
|
||||
* @param[out] output: output block
|
||||
*
|
||||
* @retval ::-1: The aes pkcs7 padding error.
|
||||
* @retval ::others: The aes pkcs7 padding output length.
|
||||
* *****************************************************************************************
|
||||
*/
|
||||
int crypto_aes_pkcs7_padding(uint8_t *input, uint32_t length, uint8_t *output);
|
||||
|
||||
/**
|
||||
* ****************************************************************************************
|
||||
* @brief zero padding algorithm
|
||||
*
|
||||
* @param[in] input: input block
|
||||
* @param[in] length: input length
|
||||
* @param[out] output: output block
|
||||
*
|
||||
* @retval ::-1: The aes zero padding error.
|
||||
* @retval ::others: The aes zero padding output length.
|
||||
* *****************************************************************************************
|
||||
*/
|
||||
int crypto_aes_zero_padding(uint8_t *input, uint32_t length, uint8_t *output);
|
||||
|
||||
/**
|
||||
* ****************************************************************************************
|
||||
* @brief get output length
|
||||
*
|
||||
* @param[in] length: input length
|
||||
* @param[in] padding_type: padding type
|
||||
*
|
||||
* @retval ::len: The output len.
|
||||
* *****************************************************************************************
|
||||
*/
|
||||
uint32_t crypto_aes_get_output_length(uint32_t length, crypto_aes_padding_t padding_type);
|
||||
|
||||
/**
|
||||
* ****************************************************************************************
|
||||
* @brief AES-ECB block encryption/decryption
|
||||
*
|
||||
* @param[in] ctx: AES context
|
||||
* @param[in] mode: AES_ENCRYPT or AES_DECRYPT
|
||||
* @param[in] input: input block
|
||||
* @param[in] length: input length
|
||||
* @param[out] output: output block
|
||||
*
|
||||
* @retval ::-1: The aes ecb crypt error.
|
||||
* @retval ::0: The aes ecb crypt successfully.
|
||||
* *****************************************************************************************
|
||||
*/
|
||||
int crypto_aes_crypt_ecb(crypto_aes_context *ctx, uint8_t mode, uint8_t *input, uint32_t length, uint8_t *output);
|
||||
|
||||
/**
|
||||
* *****************************************************************************************
|
||||
* @brief AES-CBC buffer encryption/decryption
|
||||
* Length should be a multiple of the block
|
||||
* size (16 bytes)
|
||||
*
|
||||
* @note Upon exit, the content of the IV is updated so that you can
|
||||
* call the function same function again on the following
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If on the other hand you need to retain the contents of the
|
||||
* IV, you should either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
* @param[in] ctx: AES context
|
||||
* @param[in] mode: AES_ENCRYPT or AES_DECRYPT
|
||||
* @param[in] iv: initialization vector (updated after use)
|
||||
* @param[in] input: buffer holding the input data
|
||||
* @param[in] length: buffer holding the input data length
|
||||
* @param[out] output: buffer holding the output data
|
||||
*
|
||||
* @retval ::-1: The aes cbc crypt error.
|
||||
* @retval ::0: The aes cbc crypt successfully.
|
||||
* *****************************************************************************************
|
||||
*/
|
||||
int crypto_aes_crypt_cbc(crypto_aes_context *ctx, uint8_t mode, uint8_t iv[16], uint8_t *input, uint32_t length, uint8_t *output);
|
||||
|
||||
/**
|
||||
* *****************************************************************************************
|
||||
* @brief AES-CTR buffer encryption/decryption
|
||||
* Length should be a multiple of the block
|
||||
* size (16 bytes)
|
||||
*
|
||||
* @note Upon exit, the content of the IV is updated so that you can
|
||||
* call the function same function again on the following
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If on the other hand you need to retain the contents of the
|
||||
* IV, you should either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
* @param[in] ctx: AES context
|
||||
* @param[in] length: buffer holding the input data length
|
||||
* @param[in] nc_off: The offset in the current stream_block, for resuming within the current cipher stream.
|
||||
* The offset pointer should be 0 at the start of a stream.
|
||||
* @param[in] nonce_counter: The 128-bit nonce and counter.
|
||||
* It must be a readable-writeable buffer of 16 Bytes.
|
||||
* @param[in] stream_block: The saved stream block for resuming.
|
||||
* This is overwritten by the function.
|
||||
* It must be a readable-writeable buffer of 16 Bytes.
|
||||
* @param[in] input: buffer holding the input data
|
||||
* @param[out] output: buffer holding the output data
|
||||
*
|
||||
* @retval ::-1: The aes ctr crypt error.
|
||||
* @retval ::0: The aes ctr crypt successfully.
|
||||
* *****************************************************************************************
|
||||
*/
|
||||
int crypto_aes_crypt_ctr(crypto_aes_context *ctx, uint32_t length, uint32_t *nc_off,
|
||||
uint8_t nonce_counter[16], uint8_t stream_block[16], const uint8_t *input, uint8_t *output);
|
||||
|
||||
/**
|
||||
* *****************************************************************************************
|
||||
* @brief AES-CFB128 buffer encryption/decryption
|
||||
* Length should be a multiple of the block
|
||||
* size (16 bytes)
|
||||
*
|
||||
* @note Upon exit, the content of the IV is updated so that you can
|
||||
* call the function same function again on the following
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If on the other hand you need to retain the contents of the
|
||||
* IV, you should either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
* @param[in] ctx: AES context
|
||||
* @param[in] mode: AES operation
|
||||
* @param[in] length: buffer holding the input data length
|
||||
* @param[in] iv_off: The offset in IV (updated after use)
|
||||
* @param[in] iv: The initialization vector (updated after use)
|
||||
* @param[in] input: buffer holding the input data
|
||||
* @param[out] output: buffer holding the output data
|
||||
*
|
||||
* @retval ::-1: The aes ctr crypt error.
|
||||
* @retval ::0: The aes ctr crypt successfully.
|
||||
* *****************************************************************************************
|
||||
*/
|
||||
int crypto_aes_crypt_cfb128(crypto_aes_context *ctx, uint8_t mode, uint32_t length, uint32_t *iv_off,
|
||||
uint8_t iv[16], const uint8_t *input, uint8_t *output);
|
||||
|
||||
/**
|
||||
* *****************************************************************************************
|
||||
* @brief AES-OFB buffer encryption/decryption
|
||||
* Length should be a multiple of the block
|
||||
* size (16 bytes)
|
||||
*
|
||||
* @note Upon exit, the content of the IV is updated so that you can
|
||||
* call the function same function again on the following
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If on the other hand you need to retain the contents of the
|
||||
* IV, you should either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
* @param[in] ctx: AES context
|
||||
* @param[in] length: buffer holding the input data length
|
||||
* @param[in] iv_off: The offset in IV (updated after use)
|
||||
* @param[in] iv: The initialization vector (updated after use)
|
||||
* @param[in] input: buffer holding the input data
|
||||
* @param[out] output: buffer holding the output data
|
||||
*
|
||||
* @retval ::-1: The aes ctr crypt error.
|
||||
* @retval ::0: The aes ctr crypt successfully.
|
||||
* *****************************************************************************************
|
||||
*/
|
||||
int crypto_aes_crypt_ofb(crypto_aes_context *ctx, uint32_t length, uint32_t *iv_off,
|
||||
uint8_t iv[16], const uint8_t *input, uint8_t *output);
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CRYPTO_AES_H__ */
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
/** @} */
|
||||
@@ -0,0 +1,411 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file crypto_ecc.h
|
||||
* @author BLE Driver Team
|
||||
* @brief Header file containing functions prototypes of crypto ECC library.
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2022 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup PERIPHERAL Peripheral Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CRYPTO_DRIVER CRYPTO DRIVER
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup CRYPTO_ECC ECC
|
||||
* @brief ECC CRYPTO driver.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __CRYPTO_ECC_H__
|
||||
#define __CRYPTO_ECC_H__
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/** @defgroup CRYPTO_ECC_MACRO Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define ECC_U32_LENGTH (8) /**< ECC supported 256-bit. */
|
||||
#define ECC_HASH_SHA_256 (1) /**< ECC use hash sha256. */
|
||||
#define ECC_HASH_NONE (0) /**< ECC without hash. */
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup CRYPTO_ECC_ENUM Enumerations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief ECC Return code.
|
||||
*/
|
||||
typedef enum _algo_ecc_ret {
|
||||
|
||||
ECC_OK = 0, /**< ECC Return OK. */
|
||||
ECC_ERROR_PARAMETER = 10000, /**< ECC Return Parameter Error. */
|
||||
ECC_ERROR_SIGN, /**< ECC Return Sign Error. */
|
||||
ECC_ERROR_VERIFY, /**< ECC Return Verify Error. */
|
||||
ECC_ERROR_POINT_NOT_ON_CURVE, /**< ECC Return Point is not on curve Error. */
|
||||
ECC_ERROR_INTERFACE_EMPTY, /**< ECC Return interface not found. */
|
||||
} algo_ecc_ret_e;
|
||||
|
||||
/**
|
||||
* @brief ECC Curve type.
|
||||
*/
|
||||
typedef enum _algo_ecc_curve_type {
|
||||
|
||||
ECC_CURVE_SECP256R1, /**< NIST SECP256R1 Curve. */
|
||||
ECC_CURVE_SECP256K1, /**< NIST SECP256K1 Curve. */
|
||||
} algo_ecc_curve_type_e;
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup CRYPTO_ECC_CONTEXT_STRUCTURES Structures
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup ECC Point Structurs Definition
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Defines a data structure of a point, include x-axis and y-axis. And (0,0) is defined as the point of infinite.
|
||||
*/
|
||||
typedef struct _algo_ecc_point {
|
||||
|
||||
uint32_t x[ECC_U32_LENGTH]; /**< point' x-axis, interger format (ANSI X9.62 - 2005 (Page 27))*/
|
||||
uint32_t y[ECC_U32_LENGTH]; /**< point' y-axis, interger format (ANSI X9.62 - 2005 (Page 27))*/
|
||||
|
||||
} algo_ecc_point_t;
|
||||
/** @} */
|
||||
|
||||
/** @defgroup ECC Curve Structurs Definition
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief User defined elliptic curve description.
|
||||
*/
|
||||
typedef struct _algo_ecc_curve_parameter {
|
||||
|
||||
/**
|
||||
* parameter A in Montgomery Filed! a = a * R, denoted integer format as ANSI X9.62 - 2005 (Page 27).
|
||||
* For example NIST P256 a = {0xfffffffc,0xffffffff,0xffffffff,0x00000003,0x00000000,0x00000000,0x00000004,0xfffffffc};
|
||||
*/
|
||||
uint32_t a[ECC_U32_LENGTH]; /**< parameter A in Montgomery Filed! */
|
||||
|
||||
/**
|
||||
* parameter B in Montgomery Filed! b = b * R, denoted integer format as ANSI X9.62 - 2005 (Page 27).
|
||||
* For example NIST P256 b = {0x29c4bddf,0xd89cdf62,0x78843090,0xacf005cd,0xf7212ed6,0xe5a220ab,0x04874834,0xdc30061d};
|
||||
*/
|
||||
uint32_t b[ECC_U32_LENGTH]; /**< parameter B in Montgomery Filed! */
|
||||
|
||||
/**
|
||||
* parameter p, denoted integer format as ANSI X9.62 - 2005 (Page 27).
|
||||
* For example NIST P256 p = {0xffffffff, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff};
|
||||
*/
|
||||
uint32_t p[ECC_U32_LENGTH]; /**< parameter P in curve */
|
||||
|
||||
/**
|
||||
* parameter R ^ 2 mod p, where R = 2 ^ 256, denoted integer format as ANSI X9.62 - 2005 (Page 27).
|
||||
* For example NIST P256 R^2 mod p {0x00000004, 0xfffffffd, 0xffffffff, 0xfffffffe, 0xfffffffb, 0xffffffff, 0x00000000, 0x00000003}
|
||||
*/
|
||||
uint32_t p_r_square[ECC_U32_LENGTH]; /**< R^2 mod p */
|
||||
|
||||
/**
|
||||
* Montgomery multiplication constant for prime p
|
||||
*/
|
||||
uint32_t constp; /**< Montgomery multiplication constant for prime p */
|
||||
|
||||
/**
|
||||
* parameter p, denoted integer format as ANSI X9.62 - 2005 (Page 27).
|
||||
* For example NIST P256 n = {0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xbce6faad, 0xa7179e84, 0xf3b9cac2, 0xfc632551}
|
||||
*/
|
||||
uint32_t n[ECC_U32_LENGTH]; /**< NIST P256 n */
|
||||
|
||||
/**
|
||||
* parameter R ^ 2 mod n, where R = 2 ^ 256, denoted integer format as ANSI X9.62 - 2005 (Page 27).
|
||||
* For example NIST P256 R^2 mod n {0x66e12d94, 0xf3d95620, 0x2845b239, 0x2b6bec59, 0x4699799c, 0x49bd6fa6, 0x83244c95, 0xbe79eea2}
|
||||
*/
|
||||
uint32_t n_r_square[ECC_U32_LENGTH]; /**< R^2 mod n */
|
||||
|
||||
/**
|
||||
* Montgomery multiplication constant for prime n
|
||||
*/
|
||||
uint32_t constn; /**< Montgomery multiplication constant for prime n */
|
||||
|
||||
/**
|
||||
* parameter h for ecc curve
|
||||
*/
|
||||
uint32_t h; /**< parameter h for ecc curve */
|
||||
|
||||
/**
|
||||
* generation point for ecc curve
|
||||
*/
|
||||
algo_ecc_point_t G; /**< generation point for ecc curve */
|
||||
|
||||
} algo_ecc_curve_parameter_t;
|
||||
/** @} */
|
||||
|
||||
/** @defgroup ECC Config Structurs Definition
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief ECC Computation config
|
||||
* \note It is recommended to set config via API ecc_init_config
|
||||
*/
|
||||
typedef struct _algo_ecc_config {
|
||||
|
||||
/* Followings parameters are for Both ECC/RSA */
|
||||
/**
|
||||
* This member MUST BE specified. The default p256 params can be get from ROM
|
||||
*/
|
||||
algo_ecc_curve_parameter_t *curve; /**< ecc curve */
|
||||
|
||||
} algo_ecc_config_t;
|
||||
/** @} */
|
||||
|
||||
/** @defgroup ECDSA Config Structurs Definition
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief The ECDSA context structure
|
||||
*/
|
||||
typedef struct _algo_ecc_ecdsa_config {
|
||||
|
||||
/**
|
||||
* ECDSA compute options, include curve type.
|
||||
*/
|
||||
algo_ecc_config_t calc_options; /**< ecc config options */
|
||||
|
||||
/**
|
||||
* ECDSA our secret value, (a random number < n)
|
||||
*/
|
||||
uint32_t our_secret_value[ECC_U32_LENGTH]; /**<ECDSA our secret value, (a random number < n) */
|
||||
|
||||
/**
|
||||
* ECDSA our public value, our_public_point = our_secret_value * G
|
||||
*/
|
||||
algo_ecc_point_t our_public_point; /**<ECDSA our public value, our_public_point = our_secret_value * G */
|
||||
|
||||
/**
|
||||
* ECDSA k, just for test.
|
||||
*/
|
||||
uint32_t k[ECC_U32_LENGTH]; /**<ECDSA k value,just for test.when test end,we will delete this parameter */
|
||||
|
||||
} algo_ecc_ecdsa_config_t;
|
||||
/** @} */
|
||||
|
||||
/** @defgroup ECDH Config Structurs Definition
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief An elliptic Diffie Hellman description
|
||||
*/
|
||||
typedef struct _algo_ecc_ecdh_config {
|
||||
|
||||
/**
|
||||
* ECDH compute options, include curve type.
|
||||
*/
|
||||
algo_ecc_config_t calc_options; /**< ecc config options */
|
||||
|
||||
/**
|
||||
* ECDH our secret value, (a random number < n)
|
||||
*/
|
||||
uint32_t our_secret_value[ECC_U32_LENGTH]; /**< ECDH our secret value, (a random number < n) */
|
||||
|
||||
/**
|
||||
* ECDH our public value, our_public_point = our_secret_value * G
|
||||
*/
|
||||
algo_ecc_point_t our_public_point; /**< ECDH our public value, our_public_point = our_secret_value * G*/
|
||||
|
||||
/**
|
||||
* ECDH peer's public value
|
||||
*/
|
||||
algo_ecc_point_t peer_public_point; /**< ECDH peer's public value */
|
||||
|
||||
/**
|
||||
* ECDH shared point, shared_point = our_secret_value * peer_public_point,
|
||||
* and DHKey is shared_point.x
|
||||
*/
|
||||
algo_ecc_point_t shared_point; /**< ECDH shared point, shared_point = our_secret_value * peer_public_point */
|
||||
|
||||
} algo_ecc_ecdh_config_t;
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup CRYPTO_ECC_FUNCTIONS Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
// ECDSA APIs//
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief ECDSA init config, such as curve type and this function will internally set rng, crc32 and sha function
|
||||
*
|
||||
* @param[in] ecdsa_data: ECC ECDSA data structure, refer to \ref algo_ecc_ecdh_config_t.
|
||||
*
|
||||
* @param[in] curve: ECC curve type, refer to \ref algo_ecc_curve_type_e.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void crypto_ecc_ecdsa_init(algo_ecc_ecdsa_config_t *ecdsa_data, algo_ecc_curve_type_e curve);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief generate our ECDSA secret key and public key
|
||||
*
|
||||
* @param[in] ecdsa_data: ECC ECDSA data structure, refer to \ref algo_ecc_ecdh_config_t. Generated data are write to ecdh_data members
|
||||
*
|
||||
* @retval::ECC_ERROR_PARAMETER:NULL input pointer.
|
||||
* @retval::ECC_OK: execute successfully.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
algo_ecc_ret_e crypto_ecc_ecdsa_gen_secret_and_public(algo_ecc_ecdsa_config_t *ecdsa_data);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief sign message with private key and output signiture pair {r,s};
|
||||
* \note r, s are integer format
|
||||
*
|
||||
* @param[in] ecdsa_calc_options: algo_ecdsa_config_t
|
||||
*
|
||||
* @param[in] hash_func: choose hash function.
|
||||
*
|
||||
* @param[in] message: input message, interpreted as binary string.
|
||||
*
|
||||
* @param[in] message_byte_length: input message length in byte.
|
||||
*
|
||||
* @param[out] out_signiture_r: output 256-bit signiture r, integer format.
|
||||
*
|
||||
* @param[out] out_signiture_s: output 256-bit signiture s, integer format.
|
||||
*
|
||||
* @retval::ECC_ERROR_PARAMETER:NULL input pointer.
|
||||
* @retval::ECC_ERROR_SIGN:ECC sign failed.
|
||||
* @retval::ECC_OK: execute successfully.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
algo_ecc_ret_e crypto_ecc_ecdsa_sign(algo_ecc_ecdsa_config_t *ecdsa_calc_options, uint8_t hash_func,
|
||||
uint8_t *message, uint32_t message_byte_length,
|
||||
uint32_t out_signiture_r[ECC_U32_LENGTH], uint32_t out_signiture_s[ECC_U32_LENGTH]);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief verify signiture pair {r,s} for message;
|
||||
*
|
||||
* @param[in] ecdsa_calc_options: algo_ecdsa_config_t
|
||||
*
|
||||
* @param[in] hash_func: choose hash function.
|
||||
*
|
||||
* @param[in] message: input message, interpreted as binary string.
|
||||
*
|
||||
* @param[in] message_byte_length: input message length in byte.
|
||||
*
|
||||
* @param[in] in_signiture_r: input 256-bit signiture r, integer format.
|
||||
*
|
||||
* @param[in] in_signiture_s: input 256-bit signiture s, integer format.
|
||||
*
|
||||
* @retval::ECC_ERROR_PARAMETER:NULL input pointer.
|
||||
* @retval::ECC_ERROR_VERIFY:ECC verify failed.
|
||||
* @retval::ECC_ERROR_POINT_NOT_ON_CURVE: point add result is not on the p256 curves.
|
||||
* @retval::ECC_OK: execute successfully.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
algo_ecc_ret_e crypto_ecc_ecdsa_verify(algo_ecc_ecdsa_config_t *ecdsa_calc_options, uint8_t hash_func,
|
||||
uint8_t *message, uint32_t message_byte_length,
|
||||
uint32_t in_signiture_r[ECC_U32_LENGTH], uint32_t in_signiture_s[ECC_U32_LENGTH]);
|
||||
|
||||
// ECDH APIs//
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief ECDH init config, such as curve type and this function will internally set rng, crc32 and sha function
|
||||
*
|
||||
* @param[in] ecdh_data: ECC Diffie-Hellman data structure, refer to \ref algo_ecc_ecdh_config_t.
|
||||
*
|
||||
* @param[in] curve: ECC curve type, refer to \ref algo_ecc_curve_type_e.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void crypto_ecc_ecdh_init(algo_ecc_ecdh_config_t *ecdh_data, algo_ecc_curve_type_e curve);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief generate our ECDH secret key and public key
|
||||
*
|
||||
* @param[in] ecdh_data: ECC Diffie-Hellman data structure, refer to \ref algo_ecc_ecdh_config_t. Generated data are write to ecdh_data members
|
||||
*
|
||||
* @retval::ECC_ERROR_PARAMETER:NULL input pointer.
|
||||
* @retval::ECC_OK: execute successfully.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
algo_ecc_ret_e crypto_ecc_ecdh_gen_secret_and_public(algo_ecc_ecdh_config_t *ecdh_data);
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief generate shared secret via peer's public key
|
||||
*
|
||||
* @param[in] ecdh_data: ECC Diffie-Hellman data structure, refer to \ref algo_ecc_ecdh_config_t. Generated data are write to ecdh_data members
|
||||
*
|
||||
* @param[in] qb: peer's public information.
|
||||
*
|
||||
* @retval::ECC_ERROR_PARAMETER:NULL input pointer.
|
||||
* @retval::ECC_ERROR_POINT_NOT_ON_CURVE:qb is not on the p256 curves.
|
||||
* @retval::ECC_OK: execute successfully.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
algo_ecc_ret_e crypto_ecc_ecdh_compute_shared(algo_ecc_ecdh_config_t *ecdh_data, algo_ecc_point_t *qb);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CRYPTO_ECC_H__ */
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
/** @} */
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file crypto_ecc_port.h
|
||||
* @author BLE Driver Team
|
||||
* @brief Header file containing functions prototypes of crypto ECC library.
|
||||
*
|
||||
****************************************************************************************
|
||||
* @attention
|
||||
#####Copyright (c) 2022 GOODIX
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of GOODIX nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __CRYPTO_ECC_PORT_H__
|
||||
#define __CRYPTO_ECC_PORT_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "crypto_ecc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint32_t hw_ecc_rng32(void);
|
||||
void hw_ecc_point_mul(algo_ecc_config_t *ecc_calc_options,
|
||||
uint32_t k[ECC_U32_LENGTH],
|
||||
algo_ecc_point_t *Q,
|
||||
algo_ecc_point_t *result);
|
||||
void hw_ecc_sha(const uint8_t *message, uint32_t message_byte_length, uint8_t output[32]);
|
||||
void hw_ecc_modular_compare(algo_ecc_config_t *ecc_calc_options,
|
||||
uint32_t in_a[],
|
||||
uint32_t in_prime[],
|
||||
uint32_t result[]);
|
||||
void ecc_modular_inverse(algo_ecc_config_t *ecc_config,
|
||||
uint32_t in_a[],
|
||||
uint32_t in_prime[],
|
||||
uint32_t r_square[],
|
||||
uint32_t constq,
|
||||
uint32_t out_a_inverse[]);
|
||||
void hw_ecc_montgomery_inverse(
|
||||
algo_ecc_config_t *ecc_calc_options, uint32_t in_a[], uint32_t in_prime[], uint32_t constp, uint32_t out_x[]);
|
||||
void hw_ecc_modular_sub(
|
||||
algo_ecc_config_t *ecc_calc_options, uint32_t in_a[], uint32_t in_b[], uint32_t in_prime[], uint32_t result[]);
|
||||
void hw_ecc_montgomery_mul(algo_ecc_config_t *ecc_calc_options,
|
||||
uint32_t in_a[],
|
||||
uint32_t in_b[],
|
||||
uint32_t in_prime[],
|
||||
uint32_t constp,
|
||||
uint32_t result[]);
|
||||
void hw_ecc_modular_add(
|
||||
algo_ecc_config_t *ecc_calc_options, uint32_t in_a[], uint32_t in_b[], uint32_t in_prime[], uint32_t result[]);
|
||||
void ecc_modular_multiply(algo_ecc_config_t *ecc_config,
|
||||
uint32_t in_a[],
|
||||
uint32_t in_b[],
|
||||
uint32_t in_prime[],
|
||||
uint32_t r_square[],
|
||||
uint32_t constq,
|
||||
uint32_t out_result[]);
|
||||
uint32_t ecc_is_infinite_point(algo_ecc_point_t *point);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CRYPTO_ECC_PORT_H__ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user