!121 升级GR551x_SDK_v2.0.2

Merge pull request !121 from goodix_zhaoxingyu/GR551x_SDK_v202
This commit is contained in:
openharmony_ci
2024-06-20 02:57:46 +00:00
committed by Gitee
538 changed files with 198519 additions and 16597 deletions
+1 -1
View File
@@ -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
View File
@@ -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 -3
View File
@@ -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" ]
}
+86
View File
@@ -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" ]
}
}
}
-1
View File
@@ -5,7 +5,6 @@ root {
configNum = 1;
gpioIndex = [0];
pull = [0];
handleMode = [0];
}
}
}
Executable → Regular
+5 -5
View File
@@ -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",
]
}
+2 -3
View File
@@ -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") {
}
+132 -44
View File
@@ -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__
+30 -147
View File
@@ -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__
+7 -59
View File
@@ -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",
]
}
+127
View File
@@ -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 dBm1 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",
]
}
@@ -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;
}
}
@@ -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") {
}
@@ -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 */
@@ -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
@@ -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*/
@@ -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" ]
}
+36 -37
View File
@@ -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);
}
}
+8 -3
View File
@@ -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",
]
}
+35 -33
View File
@@ -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,
+25 -15
View File
@@ -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;
+9 -11
View File
@@ -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
/** @} */
File diff suppressed because it is too large Load Diff
+131 -196
View File
@@ -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;
/** @} */
@@ -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) */
@@ -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",
]
}
+239 -128
View File
@@ -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;
+43 -42
View File
@@ -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
+231 -152
View File
@@ -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
+35 -15
View File
@@ -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" ]
}
File diff suppressed because it is too large Load Diff
+77 -44
View File
@@ -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" ]
}
@@ -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
@@ -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" ]
}
@@ -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;
}
}
@@ -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