fix xts test bug && code check

Signed-off-by: wenxing.tu <wenxing.tu@bekencorp.com>
This commit is contained in:
wenxing.tu
2022-12-29 18:37:49 +08:00
parent 2956bdf1e0
commit 0595206eca
185 changed files with 27598 additions and 12577 deletions
+1 -4
View File
@@ -11,13 +11,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
if (ohos_kernel_type == "liteos_m") {
import("//kernel/liteos_m/liteos.gni")
module_name = get_path_info(rebase_path("."), "name")
module_group(module_name) {
modules = [
"bk7235",
]
modules = [ "bk7235" ]
}
}
+17 -1
View File
@@ -25,10 +25,16 @@
<policyitem type="copyright" name="Huawei" path=".*" desc="beken use Huawei copyright"/>
<policyitem type="copyright" name="BEKEN" path=".*" desc="use beken copyright"/>
<policyitem type="copyright" name="Beken" path=".*" desc="use beken copyright"/>
<policyitem type="copyright" name="Swedish" path=".*" desc="use swedish copyright"/>
<policyitem type="copyright" name="Amazon" path=".*" desc="use Amazon copyright"/>
<policyitem type="copyright" name="Valentin" path=".*" desc="use Valentin copyright"/>
<policyitem type="copyright" name="Holger Weiss" path=".*" desc="use Holger Weiss copyright"/>
<policyitem type="copyright" name="Patrick Powell" path=".*" desc="use Patrick Powell copyright"/>
<policyitem type="copyright" name="Armink" path=".*" desc="use Armink copyright"/>
<policyitem type="license" name="Apache" path=".*" desc="beken use apache 2.0 license"/>
<policyitem type="license" name="BSD-3-Clause" path=".*" desc="beken use BSD-3-Clause license"/>
<policyitem type="license" name="MIT" path=".*" desc="beken use MIT license"/>
</policy>
</policy>
</policylist>
<filefilterlist>
<filefilter name="defaultFilter" desc="beken using MIT files, but invalid copyright">
@@ -40,6 +46,16 @@
</filefilter>
<filefilter name="defaultFilter" desc="not use copyright">
<filteritem type="filepath" name="bk7235/liteos_m/bk_sdk_armino/middleware/driver/uart/printf.c" desc="not use copyright"/>
<filteritem type="filepath" name="bk7235/liteos_m/bk_sdk_armino/components/easy_flash/inc/easyflash.h" desc="not use copyright"/>
<filteritem type="filepath" name="bk7235/liteos_m/bk_sdk_armino/components/easy_flash/port/ef_cfg.h" desc="not use copyright"/>
<filteritem type="filepath" name="bk7235/liteos_m/bk_sdk_armino/components/easy_flash/port/ef_port.c" desc="not use copyright"/>
<filteritem type="filepath" name="bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/easyflash.c" desc="not use copyright"/>
<filteritem type="filepath" name="bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_env.c" desc="not use copyright"/>
<filteritem type="filepath" name="bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_env_wl.c" desc="not use copyright"/>
<filteritem type="filepath" name="bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_iap.c" desc="not use copyright"/>
<filteritem type="filepath" name="bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_log.c" desc="not use copyright"/>
<filteritem type="filepath" name="bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_utils.c" desc="not use copyright"/>
<filteritem type="filepath" name="bk7235/liteos_m/bk_sdk_armino/middleware/soc/bk7235/bk7235_bsp.sag" desc="not use copyright"/>
<filteritem type="filepath" name="bk7235/liteos_m/bk_sdk_armino/middleware/soc/common/dualcore_cpu1.sag" desc="not use copyright"/>
<filteritem type="filepath" name="Kconfig.liteos_m.defconfig" desc="not use copyright"/>
+32 -1
View File
@@ -14,10 +14,41 @@
if (ohos_kernel_type == "liteos_m") {
import("//build/lite/config/component/lite_component.gni")
import("//build/lite/config/subsystem/lite_subsystem.gni")
import("//kernel/liteos_m/config.gni")
import("//kernel/liteos_m/liteos.gni")
module_name = get_path_info(rebase_path("."), "name")
module_group(module_name) {
modules = [ "liteos_m" ]
# deps = [ "src:bk_liteos_adapter" ]
deps = [
":copy_libs",
":encrypt",
]
}
copy("copy_libs") {
sources = [
"liteos_m/bk_sdk_armino/components/bk_libs/bk7235_openharmony/libs/libbt.a",
"liteos_m/bk_sdk_armino/components/bk_libs/bk7235_openharmony/libs/libwifi.a",
]
outputs = [ "$root_build_dir/libs/{{source_file_part}}" ]
}
copy("encrypt") {
sources = [ "${device_path}/encrypt" ]
outputs = [ "$root_build_dir/encrypt" ]
}
build_ext_component("build_7235_sdk") {
exec_path = rebase_path("${root_out_dir}")
ENCRYPT_FLAG = "0 0 0 0"
command = "rm -rf ${exec_path}/build"
command += "&& mkdir -p ${exec_path}/build"
command += "&& ${exec_path}/encrypt ${exec_path}/${liteos_name}.bin ${ENCRYPT_FLAG}"
command += "&& mv ${exec_path}/${liteos_name}_crc.bin ${exec_path}/build/all_2M.1220.bin"
deps = [
"${device_path}:bk_sdk",
"//kernel/liteos_m:build_kernel_image",
]
}
}
@@ -1,36 +1,32 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/lite/ndk/ndk.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
static_library("btservice") {
sources = [
"src/ohos_bt_hal.c",
"src/ble_test.c",
]
include_dirs = [
]
include_dirs = [
"${beken_sdk_dir}/components/bk_ble/ble_v5/include",
]
include_dirs += bk_hal_include_dirs
}
if (ohos_kernel_type == "liteos_m") {
ndk_lib("bluetooth_ndk") {
deps = [ ":btservice" ]
head_files =
[ "//foundation/communication/bluetooth/interfaces/innerkits/native_c/include" ]
}
}
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/lite/ndk/ndk.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
static_library("btservice") {
sources = [
"src/ble_test.c",
"src/ohos_bt_hal.c",
]
include_dirs = []
include_dirs = [ "${beken_sdk_dir}/components/bk_ble/ble_v5/include" ]
include_dirs += bk_hal_include_dirs
}
if (ohos_kernel_type == "liteos_m") {
ndk_lib("bluetooth_ndk") {
deps = [ ":btservice" ]
head_files = [ "//foundation/communication/bluetooth/interfaces/innerkits/native_c/include" ]
}
}
@@ -15,8 +15,6 @@ import("${board_adapter_dir}/hals/sdk_dir.gni")
static_library("hal_wifiaware") {
sources = [ "source/hal_wifiaware.c" ]
include_dirs = [
"//foundation/communication/wifi_aware/interfaces/kits",
]
include_dirs = [ "//foundation/communication/wifi_aware/interfaces/kits" ]
include_dirs += bk_hal_include_dirs
}
@@ -19,11 +19,8 @@ static_library("wifiservice") {
"source/wifi_device_util.c",
"source/wifi_hotspot.c",
]
defines = [
"CFG_SUPPORT_LITEOS",
]
include_dirs = [
]
defines = [ "CFG_SUPPORT_LITEOS" ]
include_dirs = []
include_dirs += bk_hal_include_dirs
}
+32 -35
View File
@@ -1,35 +1,32 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/lite/ndk/ndk.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
static_library("hal_iothardware") {
sources = [
"hal_iot_flash.c",
"hal_iot_gpio.c",
"hal_iot_i2c.c",
"hal_iot_pwm.c",
"hal_iot_uart.c",
"hal_iot_watchdog.c",
"hal_lowpower.c",
"hal_reset.c",
# "iot_test.c",
]
defines = [
"CFG_SUPPORT_LITEOS",
]
include_dirs = [
]
include_dirs += bk_hal_include_dirs
}
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/lite/ndk/ndk.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
static_library("hal_iothardware") {
sources = [
"hal_iot_flash.c",
"hal_iot_gpio.c",
"hal_iot_i2c.c",
"hal_iot_pwm.c",
"hal_iot_uart.c",
"hal_iot_watchdog.c",
"hal_lowpower.c",
"hal_reset.c",
# "iot_test.c",
]
defines = [ "CFG_SUPPORT_LITEOS" ]
include_dirs = []
include_dirs += bk_hal_include_dirs
}
+12 -14
View File
@@ -1,19 +1,17 @@
declare_args() {
bk_hal_include_dirs = [
"//base/iothardware/peripheral/interfaces/inner_api",
"//foundation/communication/wifi_lite/interfaces/wifiservice",
"//foundation/communication/bluetooth/interfaces/inner_api/include/c_header",
"//foundation/systemabilitymgr/samgr_lite/interfaces/kits/samgr",
"//commonlibrary/utils_lite/include",
"//commonlibrary/utils_lite/hals/file",
"//base/iothardware/peripheral/interfaces/inner_api",
"//foundation/communication/wifi_lite/interfaces/wifiservice",
"//foundation/communication/bluetooth/interfaces/inner_api/include/c_header",
"//foundation/systemabilitymgr/samgr_lite/interfaces/kits/samgr",
"//commonlibrary/utils_lite/include",
"//commonlibrary/utils_lite/hals/file",
"${beken_sdk_dir}/build/openharmony/${beken_chip_type}/armino_as_lib/include",
"${beken_sdk_dir}/build/openharmony/${beken_chip_type}/armino_as_lib/include/modules",
"${beken_sdk_dir}/build/openharmony/${beken_chip_type}/armino_as_lib/include/driver",
"${beken_sdk_dir}/build/openharmony/${beken_chip_type}/armino_as_lib/include/arch/compiler",
"${beken_sdk_dir}/build/openharmony/${beken_chip_type}/armino_as_lib/include/extra",
"${beken_sdk_dir}/build/openharmony/${beken_chip_type}/armino_as_lib/${beken_chip_type}/config",
"${beken_sdk_dir}/middleware/arch/riscv/include",
"${beken_sdk_dir}/components/bk_rtos/liteos_m_mst",
"${beken_sdk_dir}",
"${beken_sdk_dir}/include",
"${beken_sdk_dir}/include/driver",
"${beken_sdk_dir}/include/extra",
"${beken_sdk_dir}/middleware/arch/riscv/include",
"${beken_sdk_dir}/components/bk_rtos/liteos_m_mst",
]
}
+2 -2
View File
@@ -17,8 +17,8 @@ import("${board_adapter_dir}/hals/sdk_dir.gni")
static_library("hal_update_static") {
sources = [ "hal_hota_board.c" ]
include_dirs = [
"//base/update/ota_lite/hals",
"//base/update/ota_lite/interfaces/kits",
"//base/update/sys_installer_lite/hals",
"//base/update/sys_installer_lite/interfaces/kits",
]
include_dirs += bk_hal_include_dirs
}
-1
View File
@@ -11,7 +11,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/lite/config/component/lite_component.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
+1 -3
View File
@@ -14,7 +14,5 @@
import("//kernel/liteos_m/liteos.gni")
module_name = get_path_info(rebase_path("."), "name")
module_group(module_name) {
modules = [
# "components",
]
modules = [ "bk_sdk_armino" ]
}
+67
View File
@@ -0,0 +1,67 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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("${beken_sdk_dir}/sdkconfig.gni")
if (ohos_kernel_type == "liteos_m") {
import("//kernel/liteos_m/liteos.gni")
module_name = get_path_info(rebase_path("."), "name")
config("board_config") {
ldflags = [
"-std=c99",
"-mstrict-align",
"-Wl,--gc-sections",
"-ffunction-sections",
"-fdata-sections",
"-D__LITEOS__",
"-DCFG_SUPPORT_LITEOS",
"-DBEKEN_PLATFORM",
"-Wno-strict-prototypes",
"-Wno-parentheses",
]
include_dirs = [
".",
"include",
]
}
module_group(module_name) {
modules = []
deps = [
"components/base64",
"components/bk_adapter",
"components/bk_ate",
"components/bk_cli",
"components/bk_event",
"components/bk_init",
"components/bk_log",
"components/bk_netif",
"components/bk_os:bk_os",
"components/bk_ps:bk_ps",
"components/bk_startup",
"components/bk_system",
"components/easy_flash",
"components/media",
"components/saradc_intf",
"components/security",
"components/temp_detect",
"components/utf8:utf8",
"middleware/arch:arch",
"middleware/boards:boards",
"middleware/driver:driver",
"middleware/soc:soc",
"projects",
]
}
}
@@ -1 +0,0 @@
tools/build_tools/build_files/CMakeLists.txt
-1
View File
@@ -1 +0,0 @@
tools/build_tools/build_files/Kconfig
-1
View File
@@ -1 +0,0 @@
tools/build_tools/build_files/Makefile
+22
View File
@@ -0,0 +1,22 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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_name = get_path_info(rebase_path("."), "name")
module_group(module_name) {
modules = [
#"bk_ps",
#"bk_os",
#"bk_utf8",
]
}
@@ -1,21 +0,0 @@
set(incs)
set(srcs)
if (CONFIG_AT_CMD)
list(APPEND incs
include
)
list(APPEND srcs
"src/at_common.c"
"src/ble_at_command.c"
"src/video_at_command.c"
"src/wifi_at_command.c"
)
if (CONFIG_BT)
list(APPEND srcs
"src/bt_at_command.c")
endif()
endif()
armino_component_register(SRCS "${srcs}" INCLUDE_DIRS "${incs}" REQUIRES bk_ble bk_bt bk_common bk_log PRIV_REQUIRES bk_ble)
#ali_mqtt video
@@ -1,3 +0,0 @@
config AT_CMD
bool "Enable AT_CMD"
default n
@@ -1,123 +0,0 @@
/*
// Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 AT_BLE_COMMON_H_
#define AT_BLE_COMMON_H_
//#if (CONFIG_BLE_5_X || CONFIG_BTDM_5_2)
#include "at_common.h"
/// reference common_bt_defines.h
#define ADV_INTERVAL_MIN 0x0020 //(20 ms)
#define ADV_INTERVAL_MAX 0x4000 //(10.24 sec)
#define CON_INTERVAL_MIN 0x0006 //(7.5 msec)
#define CON_INTERVAL_MAX 0x0C80 //(4 sec)
/// Supervision TO (N*10ms) (chapter 2.E.7.8.12)
#define CON_SUP_TO_MIN 0x000A //(100 msec)
#define CON_SUP_TO_MAX 0x0C80 //(32 sec)
/// Scanning interval (in 625us slot) (chapter 2.E.7.8.10)
#define SCAN_INTERVAL_MIN 0x0004 //(2.5 ms)
#define SCAN_INTERVAL_MAX 0x4000 //(10.24 sec)
#define SCAN_INTERVAL_DFT 0x0010 //(10 ms)
/// Scanning window (in 625us slot) (chapter 2.E.7.8.10)
#define SCAN_WINDOW_MIN 0x0004 //(2.5 ms)
#define SCAN_WINDOW_MAX 0x4000 //(10.24 sec)
#define SCAN_WINDOW_DFT 0x0010 //(10 ms)
/// Connection latency (N*cnx evt) (chapter 2.E.7.8.12)
#define CON_LATENCY_MIN 0x0000
#define CON_LATENCY_MAX 0x01F3 // (499)
#define UNKNOW_ACT_IDX 0xFFU
#define AT_BLE_MAX_ACTV bk_ble_get_max_actv_idx_count()
#define AT_BLE_MAX_CONN bk_ble_get_max_conn_idx_count()
// sync actv state machine, reference actv_state_t
typedef enum {
AT_ACTV_IDLE,
/////adv
AT_ACTV_ADV_CREATED,
AT_ACTV_ADV_STARTED,
////////scan
AT_ACTV_SCAN_CREATED,
AT_ACTV_SCAN_STARTED,
AT_ACTV_INIT_CREATED,
AT_ACTV_PER_SYNC_CREATED,
AT_ACTV_PER_SYNC_STARTED,
} at_actv_state;
/// Initing state machine, reference app_init_state
enum at_init_state
{
/// Iint activity does not exists
AT_INIT_STATE_IDLE = 0,
/// Creating Iint activity
AT_INIT_STATE_CREATING,
/// Iint activity created
AT_INIT_STATE_CREATED,
/// WAIT Start Iint activity
AT_INIT_STATE_WAIT_CONNECTTING = 3,
/// Starting Iint activity
AT_INIT_STATE_CONNECTTING = 4,
/// Iint activity conected
AT_INIT_STATE_CONNECTTED = 5,
/// Stopping Iint activity
AT_INIT_STATE_STOPPING = 6,
};
/// Own BD address source of the device
enum gapm_own_addr
{
/// Public or Private Static Address according to device address configuration
BLE_STATIC_ADDR,
/// Generated resolvable private random address
BLE_GEN_RSLV_ADDR,
/// Generated non-resolvable private random address
BLE_GEN_NON_RSLV_ADDR,
};
enum le_phy_mask
{
/// The Host prefers to use the LE 1M transmitter/receiver PHY (possibly among others)
PHY_1MBPS_BIT = (1<<0),
PHY_1MBPS_POS = (0),
/// The Host prefers to use the LE 2M transmitter/receiver PHY (possibly among others)
PHY_2MBPS_BIT = (1<<1),
PHY_2MBPS_POS = (1),
/// The Host prefers to use the LE Coded transmitter/receiver PHY (possibly among others)
PHY_CODED_BIT = (1<<2),
PHY_CODED_POS = (2),
/// The Host prefers to use the LE Coded transmitter/receiver PHY (possibly among others)
PHY_ALL = (PHY_1MBPS_BIT | PHY_2MBPS_BIT | PHY_CODED_BIT),
};
enum le_coded_phy_option {
/// The host no preferred
CODED_NO_PREFEER = 0,
CODED_S2_PREFEER,
CODED_S8_PREFEER,
};
enum
{
PRF_TASK_ID_BOARDING = 10,
PRF_TASK_ID_MAX,
};
#endif
//#endif
@@ -1,91 +0,0 @@
/*
// Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 AT_COMMON_H_
#define AT_COMMON_H_
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <components/log.h>
#include <os/mem.h>
#include <os/str.h>
#include <os/os.h>
//#if (CONFIG_BLE_5_X || CONFIG_BTDM_5_2)
#include "modules/ble.h"
#include "modules/bt.h"
#include "ble_api_5_x.h"
//#endif
#include <common/bk_kernel_err.h>
#define MAX_BT_AT_CMD_LEN 20
#define MAX_BLE_AT_CMD_LEN 64
#define MAX_WIFI_AT_CMD_LEN 30
#define MAX_VIDEO_AT_CMD_LEN 10
#define AT_SYNC_CMD_TIMEOUT_MS 4000
#define AT_CMDRSP_HEAD "CMDRSP:"
#define AT_READY_MSG "\r\nready\r\n"
#define AT_CMD_RSP_SUCCEED "CMDRSP:OK\r\n"
#define AT_CMD_RSP_ERROR "CMDRSP:ERROR\r\n"
#define AT_CMDMSG_ERROR_RSP "CMDRSP:ERROR\r\n"
#define AT_RET_CHAR '\r'
#define AT_END_CHAR '\n'
#define AT_EVENT_HEAD "EVT:"
#define AT_EVT_WLAN_DISCONNECTED "EVT:WLAN DISCONNECTED\r\n"
#define AT_EVT_WLAN_CONNECTED "EVT:WLAN CONNECTED\r\n"
#define AT_EVT_GOT_IP "EVT:GOT-IP\r\n"
typedef struct
{
/** The command index*/
const uint8_t idx;
/** The name of the at command */
const char *name;
/** is the unsync command**/
bool is_sync_cmd;
/** The help text associated with the command */
const char *help;
/** The function that should be invoked for this command. */
int (*function) (char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
}at_command_t;
//#if (CONFIG_BLE_5_X || CONFIG_BTDM_5_2)
const at_command_t *lookup_bt_at_command(char *str1);
const at_command_t *lookup_ble_at_command(char *str1);
const at_command_t *lookup_bt_at_command(char *str1);
void at_set_data_handle(uint8_t *out, char *buff, uint8_t len);
int get_addr_from_param(bd_addr_t *bdaddr, char *input_param);
int ble_at_cmd_cnt(void);
int bt_at_cmd_cnt(void);
extern const at_command_t ble_at_cmd_table[MAX_BLE_AT_CMD_LEN];
extern const at_command_t bt_at_cmd_table[MAX_BT_AT_CMD_LEN];
//#endif
#if CONFIG_LWIP
const at_command_t *lookup_wifi_at_command(char *str1);
int wifi_at_cmd_cnt(void);
extern const at_command_t wifi_at_cmd_table[MAX_WIFI_AT_CMD_LEN];
#endif
const at_command_t *lookup_video_at_command(char *str1);
int video_at_cmd_cnt(void);
extern const at_command_t video_at_cmd_table[MAX_VIDEO_AT_CMD_LEN];
#endif
@@ -1,178 +0,0 @@
/*
// Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "at_common.h"
#if CONFIG_BT
#include "bt_include.h"
#endif
//#if (CONFIG_BLE_5_X || CONFIG_BTDM_5_2)
const at_command_t *lookup_ble_at_command(char *str1)
{
uint8_t type = bk_ble_get_controller_stack_type();
if(type != BK_BLE_CONTROLLER_STACK_TYPE_BLE_5_X &&
type != BK_BLE_CONTROLLER_STACK_TYPE_BTDM_5_2)
{
os_printf("%s stack type %d not support\n", __func__, type);
return NULL;
}
for (int i = 0; i < ble_at_cmd_cnt(); i++)
{
if (ble_at_cmd_table[i].name == NULL) {
i++;
continue;
}
if(!os_strcmp(ble_at_cmd_table[i].name, str1))
{
return &ble_at_cmd_table[i];
}
}
return NULL;
}
#if CONFIG_BT
const at_command_t *lookup_bt_at_command(char *str1)
{
uint8_t type = bk_bt_get_controller_stack_type();
if(type != BK_BT_CONTROLLER_STACK_TYPE_BTDM_5_2)
{
os_printf("%s stack type %d not support\n", __func__, type);
return NULL;
}
for (int i = 0; i < bt_at_cmd_cnt(); i++)
{
if (bt_at_cmd_table[i].name == NULL) {
i++;
continue;
}
if(!os_strcmp(bt_at_cmd_table[i].name, str1))
{
return &bt_at_cmd_table[i];
}
}
return NULL;
}
#endif
#if CONFIG_LWIP
const at_command_t *lookup_wifi_at_command(char *str1)
{
for (int i = 0; i < wifi_at_cmd_cnt(); i++)
{
if (wifi_at_cmd_table[i].name == NULL) {
i++;
continue;
}
if(!os_strcmp(wifi_at_cmd_table[i].name, str1))
{
return &wifi_at_cmd_table[i];
}
}
return NULL;
}
#endif
void at_set_data_handle(uint8_t *out, char *buff, uint8_t len)
{
char temp[3];
int i = 0, j = 0;
for (i = 0; i < len;)
{
os_memcpy(temp, buff + i, 2);
temp[2] = '\0';
i = i + 2;
out[j++] = os_strtoul(temp, NULL, 16) & 0xFF;
}
}
int get_addr_from_param(bd_addr_t *bdaddr, char *input_param)
{
int err = kNoErr;
uint8_t addr_len = os_strlen(input_param);
char temp[3];
uint8_t j = 1;
uint8_t k = 0;
if ( addr_len != (BK_BLE_GAP_BD_ADDR_LEN * 2 + 5))
{
err = kParamErr;
return err;
}
for (uint8_t i = 0; i < addr_len; i++)
{
if (input_param[i] >= '0' && input_param[i] <= '9')
{
temp[k] = input_param[i];
k += 1;
}
else if (input_param[i] >= 'a' && input_param[i] <= 'f')
{
temp[k] = input_param[i];
k += 1;
}
else if (input_param[i] >= 'A' && input_param[i] <= 'F')
{
temp[k] = input_param[i];
k += 1;
}
else if (input_param[i] == ':')
{
temp[k] = '\0';
bdaddr->addr[BK_BLE_GAP_BD_ADDR_LEN - j] = os_strtoul(temp, NULL, 16) & 0xFF;
k = 0;
j++;
}
else
{
err = kParamErr;
return err;
}
if (i == (addr_len - 1))
{
temp[k] = '\0';
bdaddr->addr[BK_BLE_GAP_BD_ADDR_LEN - j] = os_strtoul(temp, NULL, 16) & 0xFF;
k = 0;
}
}
return kNoErr;
}
//#endif
const at_command_t *lookup_video_at_command(char *str1)
{
for (int i = 0; i < video_at_cmd_cnt(); i++)
{
if (video_at_cmd_table[i].name == NULL) {
i++;
continue;
}
if(!os_strcmp(video_at_cmd_table[i].name, str1))
{
return &video_at_cmd_table[i];
}
}
return NULL;
}
File diff suppressed because it is too large Load Diff
@@ -1,539 +0,0 @@
/*
// Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include "at_common.h"
#include <driver/gpio.h>
#include "modules/bt.h"
#include "modules/bt_types.h"
#include "ethermind_export/bt_defines.h"
#if CONFIG_BT
#include "bt_include.h"
#endif
#define INQUIRY_LAP 0x9e8B33U
#define INQUIRY_LEN 0x0A
#define CONNECTION_PACKET_TYPE 0xcc18
#define CONNECTION_PAGE_SCAN_REPETITIOIN_MODE 0x01
#define CONNECTION_CLOCK_OFFSET 0x00
#define DISCONNECT_REASON 0x16
#define SPP_HANDLE_INVALID 0xFFU
#define PRINT_FUNC os_printf("%s \n", __func__)
#define SPP_ENABLE_DATA_CNF_LOG
#define BT_DEVICE_ADDR_ONLY_FRMT_SPECIFIER\
"ADDR: %02X:%02X:%02X:%02X:%02X:%02X"
#define BT_DEVICE_ADDR_ONLY_SPACED_FRMT_SPECIFIER\
"ADDR: %02X %02X %02X %02X %02X %02X"
#define BT_DEVICE_ADDR_ONLY_PRINT_STR(ref)\
(ref)[0U],(ref)[1U],(ref)[2U],(ref)[3U],(ref)[4U],(ref)[5U]
#define BT_DEVICE_ADDR_FRMT_SPECIFIER\
"ADDR: %02X:%02X:%02X:%02X:%02X:%02X, TYPE: %02X"
#define BT_DEVICE_ADDR_SPACED_FRMT_SPECIFIER\
"ADDR: %02X %02X %02X %02X %02X %02X, TYPE: %02X"
#define BT_IGNORE_UNUSED_PARAM(v) (void)(v)
typedef enum{
STATE_DISCONNECT,
STATE_CONNECTED,
STATE_PROFILE_DISCONNECT,
STATE_PROFILE_CONNECTED,
}connect_state_s;
typedef struct{
uint16_t conn_handle;
uint8_t conn_state;
bd_addr_t peer_addr;
uint8_t spp_init;
SPP_HANDLE spp_handle;
uint32_t spp_record_handle;
uint8_t local_server_channel;
uint8_t peer_server_channel;
}spp_env_s;
static bt_err_t at_cmd_status = BK_ERR_BT_SUCCESS;
static beken_semaphore_t bt_at_cmd_sema = NULL;
static uint16_t conn_handle = 0xff;
static spp_env_s spp_env;
static API_RESULT bt_spp_event_notify_cb
(
/* IN */ SPP_HANDLE spp_handle,
/* IN */ SPP_EVENTS spp_event,
/* IN */ API_RESULT status,
/* IN */ void * data,
/* IN */ UINT16 data_length
);
static int bt_start_inquiry_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
static int bt_create_connection_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
static int bt_disconnect_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
static int bt_spp_connect_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
static void bt_at_event_cb(bt_event_t event, void *param)
{
switch (event)
{
case BT_EVENT_INQUIRY_RESULT:
{
uint8_t *addr = (uint8_t *)param;
os_printf("BT Inquiryed addr: %x %x %x %x %x %x \r\n",*(addr+5), *(addr+4), *(addr+3), *(addr+2),*(addr+1),*(addr));
}
break;
case BT_EVENT_DISCONNECT:
spp_env.conn_state = STATE_DISCONNECT;
os_printf("BT Disconnected!!! \r\n");
break;
default:
break;
}
}
static void bt_at_cmd_cb(bt_cmd_t cmd, bt_cmd_param_t *param)
{
at_cmd_status = param->status;
switch (cmd)
{
case BT_CMD_CREATE_CONNECT:
if(param->status == BK_ERR_BT_SUCCESS)
{
conn_handle = *((uint16_t *)(param->param));
}
break;
case BT_CMD_DISCONNECT:
if(conn_handle == spp_env.conn_handle)
{
os_memset(&spp_env, 0, sizeof(spp_env_s));
}
conn_handle = 0xff;
break;
case BT_CMD_SDP:
if(at_cmd_status)
{
spp_env.peer_server_channel = *((uint8_t *)param->param);
}
break;
default:
break;
}
if (bt_at_cmd_sema != NULL)
rtos_set_semaphore( &bt_at_cmd_sema );
}
const at_command_t bt_at_cmd_table[] = {
{0, "INQUIRY", 0, "start inquiry", bt_start_inquiry_handle},
{1, "CONNECT", 0, "create connection", bt_create_connection_handle},
{2, "DISCONNECT", 0, "disconnect", bt_disconnect_handle},
{3, "SPP_CONNECT", 1, "spp connect", bt_spp_connect_handle},
};
API_RESULT bt_spp_event_notify_cb
(
/* IN */ SPP_HANDLE spp_handle,
/* IN */ SPP_EVENTS spp_event,
/* IN */ API_RESULT status,
/* IN */ void * data,
/* IN */ UINT16 data_length
)
{
#ifdef SPP_ENABLE_DATA_CNF_LOG
UINT32 index;
#endif /* SPP_ENABLE_DATA_CNF_LOG */
UCHAR * l_data;
l_data = (UCHAR*)( data );
#if 0
os_printf("\n"\
"SPP HANDLE : %u\n"\
"EVENT : %d\n"\
"RESULT : 0x%04X\n",
(unsigned int) spp_handle, spp_event, status);
if (API_SUCCESS != status)
{
os_printf("\nSPP Command failure\n");
return API_FAILURE;
}
#endif /* 0 */
switch(spp_event)
{
case SPP_CONNECT_CNF:
os_printf("SPP_CONNECT_CNF -> 0x%04X\n", status);
os_printf("SPP Instance Connected : %u\n",(unsigned int) spp_handle);
os_printf("Remote device " BT_DEVICE_ADDR_ONLY_FRMT_SPECIFIER " \n",
BT_DEVICE_ADDR_ONLY_PRINT_STR (l_data));
if (0x00 == status)
{
#ifdef SPP_VCOM_INTERFACE
appl_vcom_handle = vcom_connect_pl(spp_port, spp_baud, spp_flow, spp_read_cb);
#endif /* SPP_VCOM_INTERFACE */
if (bt_at_cmd_sema != NULL)
rtos_set_semaphore( &bt_at_cmd_sema );
}
break;
case SPP_CONNECT_IND:
os_printf("SPP_CONNECT_IND -> 0x%04X\n", status);
os_printf("SPP Instance Connected : %u\n",(unsigned int) spp_handle);
os_printf("Remote device " BT_DEVICE_ADDR_ONLY_FRMT_SPECIFIER " \n",
BT_DEVICE_ADDR_ONLY_PRINT_STR (l_data));
/* Set the global handle */
/* g_spp_handle = spp_handle; */
#ifdef SPP_VCOM_INTERFACE
appl_vcom_handle = vcom_connect_pl(spp_port, spp_baud, spp_flow, spp_read_cb);
#endif /* SPP_VCOM_INTERFACE */
break;
case SPP_DISCONNECT_CNF:
os_printf("SPP_DISCONNECT_CNF -> Disconnection Successful\n");
os_printf("Remote device " BT_DEVICE_ADDR_ONLY_FRMT_SPECIFIER " \n",
BT_DEVICE_ADDR_ONLY_PRINT_STR (l_data));
#ifdef SPP_VCOM_INTERFACE
if (0x00 == status)
{
vcom_disconnect_pl(appl_vcom_handle);
}
spp_env.conn_state = STATE_PROFILE_DISCONNECT;
#endif /* SPP_VCOM_INTERFACE */
break;
case SPP_DISCONNECT_IND:
os_printf("SPP_DISCONNECT_IND -> Disconnection Successful\n");
os_printf("Remote device " BT_DEVICE_ADDR_ONLY_FRMT_SPECIFIER " \n",
BT_DEVICE_ADDR_ONLY_PRINT_STR (l_data));
#ifdef SPP_VCOM_INTERFACE
vcom_disconnect_pl(appl_vcom_handle);
#endif /* SPP_VCOM_INTERFACE */
break;
case SPP_STOP_CNF:
os_printf("SPP_STOP_CNF -> Stop Successful\n");
break;
case SPP_SEND_CNF:
{
#if 0
UCHAR * buffer;
API_RESULT retval;
#endif
#ifdef SPP_ENABLE_DATA_CNF_LOG
os_printf("Received spp send cnf\n");
os_printf(" spp handle = %d\n", spp_handle);
os_printf(" Buffer = %p\n", l_data);
os_printf(" Actual Data Length = %d\n", data_length);
#else /* RFCOMM_ENABLE_DATA_WRITE_CNF_LOG */
os_printf(". ");
#endif /* RFCOMM_ENABLE_DATA_WRITE_CNF_LOG */
if (0x00 != status)
{
os_printf ("*** 0x%04X\n", status);
}
os_free(data);
#if 0
appl_count++;
if (appl_count == appl_loop)
{
os_printf("\n*** SPP Write for %d times has completed!!!\n", appl_loop);
break;
}
buffer = (UCHAR *)BT_alloc_mem(appl_nbytes);
if (NULL == buffer)
{
os_printf("*** Buffer Allocation FAILED. !!\n");
break;
}
if (2U > appl_nbytes)
{
BT_mem_set(buffer, appl_count, appl_nbytes);
}
else
{
BT_PACK_BE_2_BYTE_VAL(buffer, appl_count);
BT_mem_set((&buffer[2U]), appl_count, (appl_nbytes - 2U));
}
#ifdef SPP_ENABLE_DATA_CNF_LOG
os_printf("Allocated Buffer = %p\n", buffer);
os_printf("Initiating [%d]th spp Write ... ", appl_count);
#endif /* RFCOMM_ENABLE_DATA_WRITE_CNF_LOG */
retval = BT_spp_send
(
g_spp_handle,
buffer,
appl_nbytes
);
if (API_SUCCESS != retval)
{
os_printf("** FAILED ** !! Reason Code = 0x%04x\n", retval);
BT_free_mem(buffer);
}
else
{
#ifdef SPP_ENABLE_DATA_CNF_LOG
os_printf("Succeeded !!\n");
os_printf("Wait for Write Complete.\n");
#endif /* RFCOMM_ENABLE_DATA_WRITE_CNF_LOG */
}
#endif
}
break;
case SPP_RECVD_DATA_IND:
#ifdef SPP_FILE_OPERATION
if (0U != spp_recv_file_operation)
{
UINT16 written;
if (NULL != spp_recv_fp)
{
(BT_IGNORE_RETURN_VALUE) BT_fops_file_write(l_data, data_length, spp_recv_fp, &written);
}
os_printf(". ");
}
else
#endif /* SPP_FILE_OPERATION */
{
#ifdef SPP_ENABLE_DATA_CNF_LOG
os_printf("SPP_RECVD_DATA_IND -> Data received successfully\n");
os_printf("\n----------------CHAR DUMP-----------------------\n");
for (index = 0U; index < data_length; index++)
{
os_printf("%c ", l_data[index]);
}
os_printf("\n------------------------------------------------\n");
os_printf("\n----------------HEX DUMP------------------------\n");
for (index = 0U; index < data_length; index++)
{
os_printf("%02X ", l_data[index]);
}
os_printf("\n------------------------------------------------\n");
#else /* SPP_ENABLE_DATA_CNF_LOG */
os_printf(".");
#endif /* SPP_ENABLE_DATA_CNF_LOG */
}
#ifdef SPP_VCOM_INTERFACE
vcom_write_pl(appl_vcom_handle, l_data, data_length);
#endif /* SPP_VCOM_INTERFACE */
break;
default:
os_printf("\nUnknown command type\n");
break;
} /* switch */
BT_IGNORE_UNUSED_PARAM(spp_handle);
return 0x00;
}
int bt_at_cmd_cnt(void)
{
return sizeof(bt_at_cmd_table) / sizeof(bt_at_cmd_table[0]);
}
static int bt_start_inquiry_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
PRINT_FUNC;
char *msg;
int err = kNoErr;
if (bt_at_cmd_table[0].is_sync_cmd)
{
err = rtos_init_semaphore(&bt_at_cmd_sema, 1);
if(err != kNoErr){
goto error;
}
}
if(bk_bt_get_host_stack_type() == BK_BT_HOST_STACK_TYPE_ETHERMIND)
{
bk_bt_set_event_callback(bt_at_event_cb);
err = bk_bt_inquiry(INQUIRY_LAP, INQUIRY_LEN, 0, bt_at_cmd_cb);
if(!err)
{
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
if (bt_at_cmd_sema != NULL)
rtos_deinit_semaphore(&bt_at_cmd_sema);
return err;
}else
{
goto error;
}
}
error:
msg = AT_CMD_RSP_ERROR;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
if (bt_at_cmd_sema != NULL)
rtos_deinit_semaphore(&bt_at_cmd_sema);
return err;
}
static int bt_create_connection_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
PRINT_FUNC;
char *msg;
int err = kNoErr;
if (bt_at_cmd_table[1].is_sync_cmd)
{
err = rtos_init_semaphore(&bt_at_cmd_sema, 1);
if(err != kNoErr){
goto error;
}
}
if(bk_bt_get_host_stack_type() == BK_BT_HOST_STACK_TYPE_ETHERMIND)
{
bk_bt_set_event_callback(bt_at_event_cb);
bd_addr_t addr;
uint8_t allow_role_switch = 0;
err = get_addr_from_param(&addr, argv[0]);
if(err) goto error;
allow_role_switch = os_strtoul(argv[1], NULL, 16) & 0xFF;
err = bk_bt_connect(&(addr.addr[0]),
CONNECTION_PACKET_TYPE,
CONNECTION_PAGE_SCAN_REPETITIOIN_MODE,
0,
CONNECTION_CLOCK_OFFSET,
allow_role_switch,
bt_at_cmd_cb);
if(!err)
{
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
if (bt_at_cmd_sema != NULL)
rtos_deinit_semaphore(&bt_at_cmd_sema);
return err;
}else
{
goto error;
}
}
error:
msg = AT_CMD_RSP_ERROR;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
if (bt_at_cmd_sema != NULL)
rtos_deinit_semaphore(&bt_at_cmd_sema);
return err;
}
static int bt_disconnect_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
PRINT_FUNC;
char *msg;
int err = kNoErr;
if (bt_at_cmd_table[2].is_sync_cmd)
{
err = rtos_init_semaphore(&bt_at_cmd_sema, 1);
if(err != kNoErr){
goto error;
}
}
if(bk_bt_get_host_stack_type() == BK_BT_HOST_STACK_TYPE_ETHERMIND)
{
bk_bt_set_event_callback(bt_at_event_cb);
bd_addr_t addr;
err = get_addr_from_param(&addr, argv[0]);
if(err) goto error;
err = bk_bt_disconnect(&(addr.addr[0]), DISCONNECT_REASON, bt_at_cmd_cb);
if(!err)
{
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
if (bt_at_cmd_sema != NULL)
rtos_deinit_semaphore(&bt_at_cmd_sema);
return err;
}else
{
goto error;
}
}
error:
msg = AT_CMD_RSP_ERROR;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
if (bt_at_cmd_sema != NULL)
rtos_deinit_semaphore(&bt_at_cmd_sema);
return err;
}
static int bt_spp_connect_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
PRINT_FUNC;
char *msg;
int err = kNoErr;
if (bt_at_cmd_table[3].is_sync_cmd)
{
err = rtos_init_semaphore(&bt_at_cmd_sema, 1);
if(err != kNoErr){
goto error;
}
}
if(bk_bt_get_host_stack_type() == BK_BT_HOST_STACK_TYPE_ETHERMIND)
{
bk_bt_set_event_callback(bt_at_event_cb);
err = get_addr_from_param(&spp_env.peer_addr, argv[0]);
if(err) goto error;
if(!spp_env.spp_init)
{
bk_bt_spp_init(bt_spp_event_notify_cb);
spp_env.spp_handle = SPP_HANDLE_INVALID;
bk_bt_spp_start((uint32_t *)&spp_env.spp_handle, &spp_env.local_server_channel, &spp_env.spp_record_handle);
spp_env.spp_init = 1;
}
if(spp_env.conn_state != STATE_DISCONNECT)
{
os_printf("With remote device is connected, please disconnect first \r\n");
goto error;
}
bk_bt_connect(&(spp_env.peer_addr.addr[0]),
CONNECTION_PACKET_TYPE,
CONNECTION_PAGE_SCAN_REPETITIOIN_MODE,
0,
CONNECTION_CLOCK_OFFSET,
1,
bt_at_cmd_cb);
if(bt_at_cmd_sema == NULL) goto error;
err = rtos_get_semaphore(&bt_at_cmd_sema, 12*1000);
if(err != kNoErr) goto error;
if(at_cmd_status == 0x00)
{
spp_env.conn_state = STATE_CONNECTED;
spp_env.conn_handle = conn_handle;
}
bk_bt_sdp(spp_env.conn_handle, &(spp_env.peer_addr.addr[0]), bt_at_cmd_cb);
err = rtos_get_semaphore(&bt_at_cmd_sema, 60*1000);
if(err != kNoErr) goto error;
if(!at_cmd_status) goto error;
bk_bt_spp_connect(&(spp_env.peer_addr.addr[0]), spp_env.peer_server_channel, (uint32_t)spp_env.spp_handle, bt_at_cmd_cb);
err = rtos_get_semaphore(&bt_at_cmd_sema, 60*1000);
if(!err)
{
spp_env.conn_state = STATE_PROFILE_CONNECTED;
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
if (bt_at_cmd_sema != NULL)
rtos_deinit_semaphore(&bt_at_cmd_sema);
return err;
}else
{
goto error;
}
}
error:
msg = AT_CMD_RSP_ERROR;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
os_memset(&spp_env, 0, sizeof(spp_env_s));
if (bt_at_cmd_sema != NULL)
rtos_deinit_semaphore(&bt_at_cmd_sema);
return err;
}
@@ -1,350 +0,0 @@
/*
// Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "at_common.h"
#include <driver/jpeg_enc.h>
#include <driver/i2c.h>
#include <driver/dma.h>
#include <components/video_transfer.h>
#include <components/dvp_camera.h>
#include <driver/psram.h>
extern void delay(int num);//TODO fix me
#if CONFIG_PSRAM
int video_read_psram_handler(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
int video_disable_psram_handler(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
int test_psram(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
#endif
#if CONFIG_CAMERA
int video_set_yuv_psram_handler(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
int video_close_yuv_psram_handler(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
#endif //CONFIG_CAMERA
const at_command_t video_at_cmd_table[] = {
#if CONFIG_PSRAM
{0, "READPSRAM", 0, "psram", video_read_psram_handler},
{1, "DEINITPSRAM", 0, "deinit psram", video_disable_psram_handler},
{2, "TEST", 0, "psram", test_psram},
#endif
#if CONFIG_CAMERA
{3, "SETYUV", 0, "set jpeg/yuv mode and to psram", video_set_yuv_psram_handler},
{4, "CLOSEYUV", 0, "close jpeg", video_close_yuv_psram_handler},
#endif
};
int video_at_cmd_cnt(void)
{
return sizeof(video_at_cmd_table) / sizeof(video_at_cmd_table[0]);
}
#if CONFIG_PSRAM
int video_read_psram_handler(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
char *msg = NULL;
int err = kNoErr;
uint8_t i = 0;
uint32_t psram = 0x60000000;
if (argc != 0) {
os_printf("input param error\n");
err = kParamErr;
goto error;
}
err = bk_psram_init();
if (err != kNoErr) {
os_printf("psram init error\n");
err = kParamErr;
goto error;
}
os_memset((uint32_t *)psram, 0, 32);
for (i = 0; i < 8; i++) {
*((uint32 *)psram + i * 4) = i;
}
os_printf("data:\n");
for (i = 0; i < 8; i++) {
os_printf("%d ", *((uint32_t *)psram + i * 4));
}
os_printf("\n");
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return kNoErr;
error:
msg = AT_CMD_RSP_ERROR;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
int test_psram(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
char *msg = NULL;
uint32_t psram = 0x60000000;
uint8_t i = 0;
for (i = 0; i < 32; i++) {
*((uint32 *)psram + i * 4) = i * 2;
}
os_printf("data:\n");
for (i = 0; i < 32; i++) {
os_printf("%d ", *((uint32_t *)psram + i * 4));
}
os_printf("\n");
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return kNoErr;
}
int video_disable_psram_handler(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
char *msg = NULL;
int err = kNoErr;
if (argc != 0) {
os_printf("input param error\n");
err = kParamErr;
goto error;
}
err = bk_psram_deinit();
if (err != kNoErr) {
os_printf("psram deinit error\n");
err = kParamErr;
goto error;
}
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return kNoErr;
error:
msg = AT_CMD_RSP_ERROR;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
#endif // CONFIG_PSRAM
#if CONFIG_CAMERA
static void end_of_jpeg_frame(jpeg_unit_t id, void *param)
{
//os_printf("%s, %d\n", __func__, __LINE__);
}
static void end_of_yuv_frame(jpeg_unit_t id, void *param)
{
//os_printf("%s, %d\n", __func__, __LINE__);
}
int video_set_yuv_psram_handler(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
char *msg = NULL;
int err = kNoErr;
uint8_t yuv_mode = 0;
jpeg_config_t jpeg_config = {0};
i2c_config_t i2c_config = {0};
uint32_t camera_config = 0;
uint32_t camera_dev = 0;
uint32_t ppi = 0;
if (argc != 5) {
os_printf("input param error\n");
err = kParamErr;
goto error;
}
yuv_mode = os_strtoul(argv[0], NULL, 16) & 0xFF;
if (yuv_mode > 1) {
os_printf("input param error\n");
err = kParamErr;
goto error;
}
#if (!CONFIG_PSRAM)
if (yuv_mode == 1) {
os_printf("NOT have psram, jpeg encode not support yuv mode");
err = kParamErr;
goto error;
}
#endif
#if (CONFIG_PSRAM)
err = bk_psram_init();
if (err != kNoErr) {
os_printf("psram init error\n");
err = kParamErr;
goto error;
}
#endif
#if CONFIG_SYSTEM_CTRL
err = bk_jpeg_enc_driver_init();
if (err != kNoErr) {
os_printf("video init error\n");
err = kParamErr;
goto error;
}
#endif
camera_dev = os_strtoul(argv[1], NULL, 10);
ppi = os_strtoul(argv[2], NULL, 10);
camera_config = (ppi << 16) | os_strtoul(argv[3], NULL, 10);
jpeg_config.yuv_mode = yuv_mode;
switch (ppi) {
case 240:
jpeg_config.x_pixel = X_PIXEL_320;
jpeg_config.y_pixel = Y_PIXEL_240;
ppi = QVGA_320_240;
break;
case 272:
jpeg_config.x_pixel = X_PIXEL_480;
jpeg_config.y_pixel = Y_PIXEL_272;
ppi = VGA_480_272;
break;
case 480:
jpeg_config.x_pixel = X_PIXEL_640;
jpeg_config.y_pixel = Y_PIXEL_480;
ppi = VGA_640_480;
break;
case 600:
jpeg_config.x_pixel = X_PIXEL_800;
jpeg_config.y_pixel = Y_PIXEL_600;
ppi = VGA_800_600;
break;
case 720:
jpeg_config.x_pixel = X_PIXEL_1280;
jpeg_config.y_pixel = Y_PIXEL_720;
ppi = VGA_1280_720;
break;
default:
os_printf("input pixel param error\n");
err = kParamErr;
goto error;
}
if (ppi == VGA_1280_720) {
jpeg_config.sys_clk_div = 3;
jpeg_config.mclk_div = 0;
}else {
jpeg_config.sys_clk_div = 4;
jpeg_config.mclk_div = 0;
}
err = bk_jpeg_enc_dvp_init(&jpeg_config);
if (err != kNoErr) {
os_printf("jpeg init error\n");
err = kParamErr;
goto error;
}
bk_jpeg_enc_register_isr(END_OF_FRAME, end_of_jpeg_frame, NULL);
bk_jpeg_enc_register_isr(END_OF_YUV, end_of_yuv_frame, NULL);
i2c_config.baud_rate = os_strtoul(argv[4], NULL, 10) & 0xFFFFFFFF;//100000;// 400k
i2c_config.addr_mode = 0;
err = bk_i2c_init(CONFIG_CAMERA_I2C_ID, &i2c_config);
if (err != kNoErr) {
os_printf("i2c init error\n");
err = kParamErr;
goto error;
}
//err = bk_camera_set_ppi_fps(ppi, fps);
err = bk_camera_set_param(camera_dev, camera_config);
if (err != kNoErr) {
os_printf("set camera ppi and fps error\n");
err = kParamErr;
goto error;
}
bk_camera_sensor_config();
os_printf("camera init ok\n");
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return kNoErr;
error:
msg = AT_CMD_RSP_ERROR;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
int video_close_yuv_psram_handler(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
char *msg = NULL;
int err = kNoErr;
err = bk_jpeg_enc_dvp_deinit();
if (err != kNoErr) {
os_printf("jpeg deinit error\n");
err = kParamErr;
goto error;
}
os_printf("jpeg deinit ok!\n");
err = bk_i2c_deinit(CONFIG_CAMERA_I2C_ID);
if (err != kNoErr) {
os_printf("i2c deinit error\n");
err = kParamErr;
goto error;
}
os_printf("I2c deinit ok!\n");
#if CONFIG_SYSTEM_CTRL
err = bk_jpeg_enc_driver_deinit();
if (err != kNoErr) {
os_printf("video deinit error\n");
err = kParamErr;
goto error;
}
os_printf("video deinit ok!\n");
#endif
#if CONFIG_PSRAM
delay(2000);
err = bk_psram_deinit();
if (err != kNoErr) {
os_printf("psram deinit error\n");
err = kParamErr;
goto error;
}
os_printf("psram deinit ok!\n");
#endif
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return kNoErr;
error:
msg = AT_CMD_RSP_ERROR;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
#endif // CONFIG_CAMERA
@@ -1,350 +0,0 @@
/*
// Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "at_common.h"
#include <modules/wifi.h>
#include <components/netif.h>
#include "bk_wifi_wrapper.h"
#if CONFIG_LWIP
#include "net.h"
#if CONFIG_HARMONY_LWIP
#include "ping.h"
#else
#include "lwip/ping.h"
#endif
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x "
int at_wifi_scan_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
int at_wifi_staconn_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
int at_wifi_stadisconn_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
int at_wifi_ap_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
int at_wifi_stop_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
int at_wifi_state_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
int at_wifi_ping_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
const at_command_t wifi_at_cmd_table[] = {
{0, "SCAN", 1, "scan ssid...", at_wifi_scan_cmd},
{1, "STACONNECT", 1, "sta connect ap", at_wifi_staconn_cmd},
// {2, "STADISCONNECT", 0, "sta disconnect ap", at_wifi_stadisconn_cmd},
{3, "APSTART", 0, "start ap", at_wifi_ap_cmd},
{4, "STOP", 0, "disable sta/ap", at_wifi_stop_cmd},
{5, "STATE", 0, "get wifi state", at_wifi_state_cmd},
{6, "PING", 0, "wifi ping", at_wifi_ping_cmd}
};
int wifi_at_cmd_cnt(void)
{
return sizeof(wifi_at_cmd_table) / sizeof(wifi_at_cmd_table[0]);
}
int at_wifi_scan_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
char *msg = NULL;
int err = kNoErr;
if (argc == 0) {
demo_scan_app_init();
} else if (argc == 1){
uint8_t *ap_ssid;
ap_ssid = (uint8_t *)argv[0];
demo_scan_adv_app_init(ap_ssid);
}
else {
os_printf("input param error\n");
err = kParamErr;
goto error;
}
if (err == kNoErr) {
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
error:
msg = AT_CMD_RSP_ERROR;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
#include "conv_utf8_pub.h"
int at_wifi_staconn_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
char *msg = NULL;
int err = kNoErr;
char *ssid = NULL;
char *password = "";
if ((argc < 1) || (argc > 4)) {
os_printf("invalid argc number\n");
err = kParamErr;
goto error;
}
if (argc >= 1)
ssid = argv[0];
if (argc >= 2)
password = argv[1];
#if 0 //TODO support BSSID/Channel configuration
if (argc >= 3)
bssid = argv[2];
if (argc >= 4)
channel = argv[3];
#endif
char *oob_ssid_tp = ssid;
#if CONFIG_USE_CONV_UTF8
oob_ssid_tp = (char *)conv_utf8((uint8_t *)ssid);
#endif
if (oob_ssid_tp) {
demo_sta_app_init((char *)oob_ssid_tp, password);
#if CONFIG_USE_CONV_UTF8
os_free(oob_ssid_tp);
#endif
} else {
os_printf("not buf for utf8\r\n");
}
if (err == kNoErr) {
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
error:
msg = AT_CMD_RSP_ERROR;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
/*
int at_wifi_stadisconn_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
char *msg = NULL;
int err = kNoErr;
if (argc != 0)
{
os_printf("input param error\n");
err = kParamErr;
goto error;
}
err = bk_wifi_sta_disconnect();
if (err == kNoErr) {
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
error:
msg = AT_CMD_RSP_ERROR;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
*/
int at_wifi_ap_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
char *msg = NULL;
int err = kNoErr;
char *ap_ssid = NULL;
char *ap_key = "";
char *ap_channel = NULL;
if (argc == 1)
ap_ssid = argv[0];
else if (argc == 2) {
ap_ssid = argv[0];
ap_key = argv[1];
}
else if (argc == 3) {
ap_ssid = argv[0];
ap_key = argv[1];
ap_channel = argv[2];
}
else {
os_printf("input param error\n");
err = kParamErr;
goto error;
}
if (ap_ssid)
demo_softap_app_init(ap_ssid, ap_key, ap_channel);
if (err == kNoErr) {
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
error:
msg = AT_CMD_RSP_ERROR;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
int at_wifi_stop_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
char *msg = NULL;
int err = kNoErr;
if (argc == 1) {
if (os_strcmp(argv[0], "STA") == 0)
err = bk_wifi_sta_stop();
else if (os_strcmp(argv[0], "AP") == 0)
err = bk_wifi_ap_stop();
else {
os_printf("unknown WiFi interface\n");
err = kParamErr;
goto error;
}
} else {
os_printf("bad parameters\r\n");
err = kParamErr;
goto error;
}
if (err == kNoErr) {
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
error:
msg = AT_CMD_RSP_ERROR;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
int at_wifi_state_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
char *msg = NULL;
int err = kNoErr;
if (argc == 0) {
err = demo_state_app_init();
if (err == kNoErr) {
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
else {
os_printf("get link status fail!\n");
err = kGeneralErr;
goto error;
}
}
else if (argc == 1) {
wifi_link_status_t link_status = {0};
//wifi_ap_config_t ap_info = {0};
char ssid[33] = {0};
if (sta_ip_is_start()) {
os_memset(&link_status, 0x0, sizeof(link_status));
err = bk_wifi_sta_get_link_status(&link_status);
if(err != kNoErr) {
os_printf("get link status fail!\n");
err = kGeneralErr;
goto error;
}
os_memcpy(ssid, link_status.ssid, 32);
if (os_strcmp(argv[0], "RSSI") == 0) {
os_printf("sta:rssi=%d\n", link_status.rssi);
}
else if (os_strcmp(argv[0], "CHANNEL") == 0) {
os_printf("sta:channel=%d\n", link_status.channel);
}
else if (os_strcmp(argv[0], "SNR") == 0) {
os_printf("pending\n");
}
else if (os_strcmp(argv[0], "BSSID") == 0) {
os_printf("sta:bssid=" MACSTR "\n", MAC2STR(link_status.bssid));
}
else if (os_strcmp(argv[0], "IP") == 0) {
netif_ip4_config_t ap_ip4_info = {0};
err = bk_netif_get_ip4_config(NETIF_IF_STA, &ap_ip4_info);
if(err != kNoErr) {
os_printf("get ip fail!\n");
err = kGeneralErr;
goto error;
}
os_printf("ip=%s,gate=%s,mask=%s,dns=%s\r\n",
ap_ip4_info.ip, ap_ip4_info.gateway, ap_ip4_info.mask, ap_ip4_info.dns);
}
else if (os_strcmp(argv[0], "SSID") == 0) {
os_printf("sta:ssid=%d\n", ssid);
}
else {
os_printf("bad parameters\r\n");
err = kParamErr;
goto error;
}
}
else {
os_printf("sta: 0\n");
}
if(err == kNoErr) {
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
}
error:
msg = AT_CMD_RSP_ERROR;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
int at_wifi_ping_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
#if 0
char *msg = NULL;
int err = kNoErr;
uint32_t cnt = 4;
if (argc == 0) {
os_printf("Please input: ping <host address>\n");
goto error;
}
if (argc == 1 && (os_strcmp("STOP", argv[0]) == 0)) {
ping_stop();
if(err == kNoErr) {
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
}
if (argc > 1)
cnt = os_strtoul(argv[1], NULL, 10);
os_printf("ping IP address:%s\n", argv[0]);
ping_start(argv[0], cnt, 0);
if(err == kNoErr) {
msg = AT_CMD_RSP_SUCCEED;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
}
else
goto error;
error:
msg = AT_CMD_RSP_ERROR;
os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
return err;
#else
return 0;
#endif
}
#endif
+24
View File
@@ -0,0 +1,24 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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")
import("${beken_sdk_dir}/sdkconfig.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
module_name = get_path_info(rebase_path("."), "name")
static_library(module_name) {
sources = [ "base_64.c" ]
public_configs = [ ":public" ]
}
config("public") {
include_dirs = [ "." ]
}
@@ -0,0 +1,25 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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")
import("${beken_sdk_dir}/sdkconfig.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
module_name = get_path_info(rebase_path("."), "name")
static_library(module_name) {
sources = [ "lib_adapter.c" ]
include_dirs = [
"include",
"include/bk_private",
]
public_configs = [ "${beken_sdk_dir}/middleware/driver:public" ]
}
+24
View File
@@ -0,0 +1,24 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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")
import("${beken_sdk_dir}/sdkconfig.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
module_name = get_path_info(rebase_path("."), "name")
static_library(module_name) {
sources = [ "ate.c" ]
public_configs = [
"${beken_sdk_dir}/middleware/soc:public",
"${beken_sdk_dir}/middleware/driver:public",
]
}
+20
View File
@@ -0,0 +1,20 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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")
import("${beken_sdk_dir}/sdkconfig.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
config("public") {
include_dirs = [ "." ]
}
+51
View File
@@ -0,0 +1,51 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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")
import("${beken_sdk_dir}/sdkconfig.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
module_name = get_path_info(rebase_path("."), "name")
static_library(module_name) {
sources = [
"cli_aon_rtc.c",
"cli_ble.c",
"cli_efuse.c",
"cli_flash.c",
"cli_flash_test.c",
"cli_main.c",
"cli_netif.c",
"cli_rpc.c",
"cli_wdt.c",
"cli_wifi.c",
"shell_task.c",
"shell_uart.c",
]
public_configs = [
":public",
"${beken_sdk_dir}/middleware/driver:public",
"${beken_sdk_dir}/middleware/soc:public",
"${beken_sdk_dir}/components/bk_wifi:public",
"${beken_sdk_dir}/components/bk_os:public",
"${beken_sdk_dir}/components/utf8:public",
"${beken_sdk_dir}/components/bk_netif:public",
]
}
config("public") {
include_dirs = [
".",
"include",
"include/bk_private",
]
}
@@ -0,0 +1,306 @@
set(incs include include/bk_private)
list(APPEND incs
../../properties/modules/aec/
.
)
if (CONFIG_CLI)
set(srcs
#cli_adc.c
cli_ble.c
#cli_event.c
#cli_keyValue.c
#cli_gpio.c
cli_main.c
#cli_misc.c
#cli_mico.c
#cli_mem.c
#cli_os.c
cli_rpc.c
#cli_reg.c
#cli_timer.c
#cli_temp_detect.c
#cli_uart.c
#cli_security.c
#cli_spi.c
#cli_exception.c
#cli_icu.c
)
if (CONFIG_INT_WDT)
list(APPEND srcs
cli_wdt.c
)
endif()
if (CONFIG_STA_PS)
list(APPEND srcs
#cli_pwr.c
)
endif()
if (CONFIG_OTA_TFTP OR CONFIG_OTA_HTTP)
list(APPEND srcs
cli_ota.c
)
endif()
if (CONFIG_WIFI_ENABLE)
list(APPEND srcs
cli_wifi.c
#cli_phy.c
)
endif()
if (CONFIG_AIRKISS_TEST)
list(APPEND srcs
cli_airkiss.c
)
endif()
if (CONFIG_IPERF_TEST)
list(APPEND srcs
cli_iperf.c
)
endif()
if (CONFIG_GENERAL_DMA)
list(APPEND srcs
#cli_dma.c
)
endif()
if (CONFIG_SDCARD_HOST)
list(APPEND srcs
cli_sd.c
)
endif()
if (CONFIG_PWM)
list(APPEND srcs
cli_pwm.c
)
endif()
if (CONFIG_I2C)
list(APPEND srcs
cli_i2c.c
)
endif()
if (CONFIG_SUPPORT_MATTER)
list(APPEND srcs
cli_matter.c
)
endif()
if (CONFIG_FLASH)
list(APPEND srcs
cli_flash.c
)
endif()
if (CONFIG_FLASH)
list(APPEND srcs
cli_flash_test.c
)
endif()
if (CONFIG_TRNG_SUPPORT)
list(APPEND srcs
#cli_trng.c
)
endif()
if (CONFIG_I2S)
list(APPEND srcs
cli_i2s.c
)
endif()
if (CONFIG_FATFS)
list(APPEND srcs "cli_fatfs.c")
endif()
if (CONFIG_EFUSE)
list(APPEND srcs
cli_efuse.c
)
endif()
if (CONFIG_SDIO_HOST)
list(APPEND srcs
cli_sdio_host.c
)
endif()
if (CONFIG_LWIP)
list(APPEND srcs
#cli_lwip.c
)
endif()
if (CONFIG_BK_NETIF)
list(APPEND srcs
cli_netif.c
)
endif()
if (CONFIG_SHELL_ASYNCLOG)
list(APPEND srcs
shell_task.c
shell_uart.c
)
if (CONFIG_MASTER_CORE)
list(APPEND srcs
shell_mailbox_ipc.c
)
endif()
if (CONFIG_SLAVE_CORE)
list(APPEND srcs
shell_mailbox_cp1.c
)
endif()
endif()
if (CONFIG_DUAL_CORE)
list(APPEND srcs
rpc_client_gpio.c
)
endif()
if (CONFIG_SOC_BK7271)
list(APPEND srcs "cli_dsp_bk7271.c")
endif()
if (CONFIG_SOC_BK7256XX)
#list(APPEND srcs "cli_usb.c")
endif()
if (CONFIG_SOC_BK7256XX OR CONFIG_USB_UVC)
if (CONFIG_DUAL_CORE AND CONFIG_PSRAM)
list(APPEND srcs "cli_uvc.c")
endif()
endif()
if (CONFIG_SECURITYIP)
list(APPEND srcs "cli_securityip.c")
endif()
if (CONFIG_QSPI)
list(APPEND srcs
"cli_qspi.c"
)
endif()
if (CONFIG_AON_RTC_TEST)
list(APPEND srcs
"cli_aon_rtc.c"
)
endif()
if (CONFIG_JPEG_ENCODE)
list(APPEND srcs
"cli_jpegenc.c"
)
endif()
if (CONFIG_AT_CMD)
#list(APPEND srcs "cli_at.c")
endif()
if (CONFIG_LCD_TEST)
list(APPEND srcs
"cli_lcd.c")
endif() #CONFIG_LCD_TEST
if (CONFIG_DMA2D_TEST)
list(APPEND srcs
"cli_dma2d.c"
)
endif() #CONFIG_DMA2D_TEST
if (CONFIG_AUDIO_TEST AND CONFIG_AUDIO_RISCV_IP_V1_0)
list(APPEND srcs "cli_aud.c")
endif() #if(CONFIG_AUDIO)
if (CONFIG_AUDIO_TEST)
if (CONFIG_AUDIO_RISCV_IP_V1_0 AND CONFIG_DUAL_CORE)
if (NOT CONFIG_SLAVE_CORE)
list(APPEND srcs cli_aud_cp0.c)
endif()
endif()
endif()
if (CONFIG_AUDIO_AEC_TEST)
list(APPEND srcs "cli_aec.c")
endif()
if (CONFIG_AUDIO_G711_TEST)
list(APPEND srcs "cli_g711.c")
endif()
if (CONFIG_AUDIO_MP3_TEST)
list(APPEND srcs "cli_mp3.c")
endif()
if (CONFIG_FFT_TEST)
list(APPEND srcs "cli_fft.c")
endif()
if (CONFIG_SBC_TEST)
list(APPEND srcs "cli_sbc.c")
endif()
if (CONFIG_I2S_TEST)
list(APPEND srcs "cli_i2s.c")
endif()
if (CONFIG_TOUCH)
list(APPEND srcs "cli_touch.c")
endif()
if (CONFIG_CALENDAR)
list(APPEND srcs "cli_calendar.c")
endif()
endif() #if(CONFIG_CLI)
if (CONFIG_JPEG_DECODE)
list(APPEND srcs cli_jpegdec.c)
endif()
if (CONFIG_JPEG_DECODE)
list(APPEND srcs cli_jpegdec.c)
endif()
if (CONFIG_CAMERA OR CONFIG_SPIDMA)
if (CONFIG_APP_DEMO_VIDEO_TRANSFER)
list(APPEND srcs "cli_dvp.c")
endif()
endif()
if (CONFIG_DOORBELL)
list(APPEND srcs cli_doorbell.c)
endif()
if (CONFIG_PSRAM)
list(APPEND srcs cli_psram.c)
endif()
if (CONFIG_AUD_INTF_TEST)
list(APPEND srcs cli_aud_intf.c)
endif()
armino_component_register(SRCS "${srcs}"
INCLUDE_DIRS "${incs}"
REQUIRES utf8 temp_detect driver user_driver bk_system user_driver
#PRIV_REQUIRES airkiss bk_common bk_netif bk_ble bk_ps http adc_key app iperf media_common
PRIV_REQUIRES bk_common bk_netif bk_ble bk_ps bk_init at bk_wifi compal media bk_bt
)
if(CONFIG_ARCH_RISCV)
target_compile_options(${COMPONENT_LIB} PRIVATE -mno-relax)
endif()
+157
View File
@@ -0,0 +1,157 @@
menu "Cli"
config CLI
bool "Enable BK Cli"
default y
config BKREG
depends on CLI
bool "Enable BK Reg read/write"
default y
config MAX_COMMANDS
depends on CLI
int "MAX number of commands is configured by default"
range 0 65535
default 255
config IPERF_TEST
depends on CLI
bool "Enable Iperf Test"
default y
config TCP_SERVER_TEST
depends on CLI
bool "Enable TCP server Test"
default n
config AIRKISS_TEST
depends on CLI
bool "Enable Airkiss Test"
default n
config WIFI_RAW_TX_TEST
depends on CLI
bool "Enable WiFi Raw TX"
default n
#TODO Exculsive??
config I2C1_TEST
depends on CLI
bool "Enable I2C1 Test"
default n
config I2C2_TEST
depends on CLI
bool "Enable I2C2 Test"
default n
config UART_TEST
depends on CLI
bool "Enable Uart Test"
default n
config SPI_TEST
depends on CLI
bool "Enable SPI Test"
default n
config PERI_TEST
depends on CLI
bool "Enable Periperal Test"
default n
config RF_OTA_TEST
depends on CLI
bool "Enable RF OTA Test"
default n
config SHELL_ASYNCLOG
depends on CLI
bool "Enable Shell and Async log optimize"
default n
config TOUCH
depends on CLI
bool "Enable TOUCH Test"
default n
config SBC_TEST
depends on CLI
bool "Enable SBC Test"
default n
config AUDIO
depends on CLI
bool "Enable AUDIO"
default n
config EFUSE
bool "Enable Efuse"
default y
config ICU
bool "Enable ICU"
default y
config SECURITYIP
bool "Enable securityIP"
default n
config KEYVALUE
bool "Enable KEYVALUE"
default n
config IDLE_UART_OUT_TEST
bool "Enable idle uart out test"
default n
config COMPONENTS_WPA2_ENTERPRISE
bool "Enable WPA2 ENTERPRISE"
default n
config COMPONENTS_WPA_TWT_TEST
bool "Enable WPA TWT TEST"
default n
config COMPONENTS_WFA_CA
bool "WFA_CA"
default n
config ENABLE_WIFI_DEFAULT_CONNECT
bool "Enable Wi-Fi Default Connect"
default n
endmenu
menu "DUAL_CORE"
config DUAL_CORE
bool "Dual cpu core run as master core"
default n
config MASTER_CORE
depends on DUAL_CORE
bool "Dual cpu core run as master core"
default n
config SLAVE_CORE
depends on DUAL_CORE
bool "Dual cpu core run as slave core"
default n
config SLAVE_CORE_OFFSET
depends on MASTER_CORE
int "Slave core offset address default 0x2e0000"
range 0 4194304
default 3014656
config SLAVE_CORE_RESET_VALUE
depends on MASTER_CORE
int "Slave core reset value"
range 0 1
default 1
config EFUSE
bool "Enable Efuse"
default y
config ICU
bool "Enable ICU"
default y
endmenu
+124
View File
@@ -0,0 +1,124 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdlib.h>
#include <string.h>
#include <common/bk_include.h>
#include "cli_config.h"
#include "param_config.h"
#include "bk_cli.h"
#include <os/str.h>
#include <os/mem.h>
#include <os/os.h>
#include <components/log.h>
#include <common/sys_config.h>
#include <driver/uart.h>
#include "bk_uart.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CLI_TAG "cli"
#define CLI_LOGI(...) BK_LOGI(CLI_TAG, ##__VA_ARGS__)
#define CLI_LOGW(...) BK_LOGW(CLI_TAG, ##__VA_ARGS__)
#define CLI_LOGE(...) BK_LOGE(CLI_TAG, ##__VA_ARGS__)
#define CLI_LOGD(...) BK_LOGD(CLI_TAG, ##__VA_ARGS__)
#define CLI_RET_ON_INVALID_ARGC(_actual_argc, _expect_minimum_argc) do {\
if ((_actual_argc) < (_expect_minimum_argc)) {\
CLI_LOGE("invalid argc, expect %d actual %d\n", (_expect_minimum_argc), (_actual_argc));\
return;\
}\
}while(0)
int cli_wifi_init(void);
int cli_ble_init(void);
int cli_netif_init(void);
int cli_misc_init(void);
int cli_mem_init(void);
int cli_airkiss_init(void);
int cli_phy_init(void);
#if CONFIG_LWIP
int cli_lwip_init(void);
#endif
int cli_iperf_init(void);
int cli_pwr_init(void);
int cli_timer_init(void);
int cli_wdt_init(void);
int cli_trng_init(void);
int cli_efuse_init(void);
int cli_gpio_init(void);
int cli_os_init(void);
int cli_ota_init(void);
int cli_flash_init(void);
int cli_flash_test_init(void);
int cli_keyVaule_init(void);
int cli_matter_init(void);
int cli_uart_init(void);
int cli_adc_init(void);
int cli_spi_init(void);
int cli_qspi_init(void);
int cli_i2c_init(void);
int cli_aon_rtc_init(void);
int cli_sd_init(void);
int cli_fatfs_init(void);
int cli_temp_detect_init(void);
int cli_security_init(void);
int cli_mico_init(void);
int cli_peri_init(void);
int cli_event_init(void);
int cli_pwm_init(void);
int cli_reg_init(void);
int cli_dma_init(void);
int cli_exception_init(void);
int cli_icu_init(void);
int cli_at_init(void);
#if CONFIG_SECURITYIP
int cli_vault_init(void);
#endif
int cli_aud_init(void);
int cli_aud_intf_init(void);
int cli_fft_init(void);
int cli_sbc_init(void);
int cli_touch_init(void);
int cli_jpeg_init(void);
int cli_lcd_init(void);
int cli_dma2d_init(void);
int cli_i2s_init(void);
int cli_uvc_init(void);
int cli_aud_cp0_init(void);
int cli_calendar_init(void);
int cli_jpegdec_init(void);
int cli_aec_init(void);
int cli_g711_init(void);
int cli_mp3_init(void);
int cli_dvp_init(void);
int cli_doorbell_init(void);
int cli_sdio_host_init(void);
int cli_psram_init(void);
extern int hexstr2bin(const char *hex, u8 *buf, size_t len);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,230 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <os/os.h>
#include "cli.h"
#include <driver/aon_rtc.h>
static void alarm_auto_test_callback(aon_rtc_id_t id, uint8_t *name_p, void *param);
static void cli_aon_rtc_help(void)
{
CLI_LOGI("aon_rtc_driver init\r\n");
CLI_LOGI("aon_rtc_driver deinit\r\n");
CLI_LOGI("aon_rtc_register {id} {name} {period_tick} {period_cnt}, {callback}\r\n");
CLI_LOGI("aon_rtc_unregister {id} {name}\r\n");
CLI_LOGI("aon_rtc_timing_test {id} {rounds} {cycles} {set tick val}\r\n");
}
static void cli_aon_rtc_driver_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
if (argc < 2) {
cli_aon_rtc_help();
return;
}
if (os_strcmp(argv[1], "init") == 0) {
BK_LOG_ON_ERR(bk_aon_rtc_driver_init());
CLI_LOGI("aon_rtc driver init\n");
} else if (os_strcmp(argv[1], "deinit") == 0) {
BK_LOG_ON_ERR(bk_aon_rtc_driver_deinit());
CLI_LOGI("aon_rtc driver deinit\n");
} else {
cli_aon_rtc_help();
return;
}
}
static uint8_t alarm_param[12] = {'a', 'l', 'a', 'r', 'm', 'p', 'r', 'm', 0, 0, 0, 0};
static void alarm_callback(aon_rtc_id_t id, uint8_t *name_p, void *param)
{
CLI_LOGI("id=%d, name=%s %s\r\n", id, name_p, alarm_param);
}
static void cli_aon_rtc_get_time(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
uint32_t aon_rtc_id;
uint64_t tick = 0;
aon_rtc_id = os_strtoul(argv[1], NULL, 10);
tick = bk_aon_rtc_get_current_tick(aon_rtc_id);
//CLI_LOGI("id=%d, tick_h=%d tick_l=%d\r\n", aon_rtc_id, (uint32_t)(tick>>32), (uint32_t)tick);
CLI_LOGI("id=%d, tick_h=%d tick_l=%d ms\r\n", aon_rtc_id, (uint32_t)((tick/32)>>32), (uint32_t)(tick/32));
}
static void cli_aon_rtc_register_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
uint32_t aon_rtc_id;
alarm_info_t alarm_info;
if (argc != 5) {
cli_aon_rtc_help();
return;
}
aon_rtc_id = os_strtoul(argv[1], NULL, 10);
strncpy((char *)alarm_info.name, argv[2], ALARM_NAME_MAX_LEN);
alarm_info.period_tick = os_strtoul(argv[3], NULL, 10);
alarm_info.period_cnt = os_strtoul(argv[4], NULL, 10);
alarm_info.param_p = (void *)alarm_param;
alarm_info.callback = alarm_callback;
bk_alarm_register(aon_rtc_id, &alarm_info);
}
static void cli_aon_rtc_unregister_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
uint32_t aon_rtc_id;
uint8_t name[ALARM_NAME_MAX_LEN+1];
if (argc != 3) {
cli_aon_rtc_help();
return;
}
aon_rtc_id = os_strtoul(argv[1], NULL, 10);
strncpy((char *)name, argv[2], ALARM_NAME_MAX_LEN);
bk_alarm_unregister(aon_rtc_id, name);
}
static alarm_info_t s_cli_alarm_info[] =
{
{"alarm_1", (1000 * AON_RTC_MS_TICK_CNT), 0xFFFFFFFF, alarm_auto_test_callback, NULL},
{"alarm_2", (6000 * AON_RTC_MS_TICK_CNT), 0xFFFFFFFF, alarm_auto_test_callback, NULL},
{"alarm_3", (12000 * AON_RTC_MS_TICK_CNT), 0xFFFFFFFF, alarm_auto_test_callback, NULL},
{"alarm_4", (48000 * AON_RTC_MS_TICK_CNT), 0xFFFFFFFF, alarm_auto_test_callback, NULL},
{"alarm_5", (3000 * AON_RTC_MS_TICK_CNT), 0xFFFFFFFF, alarm_auto_test_callback, NULL},
{"alarm_6", (4000 * AON_RTC_MS_TICK_CNT), 0xFFFFFFFF, alarm_auto_test_callback, NULL},
};
static void alarm_auto_test_callback(aon_rtc_id_t id, uint8_t *name_p, void *param)
{
uint32_t i = 0;
uint32_t arr_size = sizeof(s_cli_alarm_info)/sizeof(alarm_info_t);
CLI_LOGI("id=%d, name=%s\r\n", id, name_p);
for(i = 0; i < arr_size; i++)
{
if(os_strcmp((const char*)s_cli_alarm_info[i].name, (const char*)name_p) == 0)
{
//forbid unregister self in the callback
//CLI_LOGI("Unregister name=%s\r\n", name_p);
//bk_alarm_unregister(id, s_cli_alarm_info[i].name);
CLI_LOGI("register name=%s\r\n", s_cli_alarm_info[(i+3)%arr_size].name);
bk_alarm_register(id, &s_cli_alarm_info[(i+3)%arr_size]);
break;
}
}
}
static void aon_rtc_autotest_start(aon_rtc_id_t id)
{
uint32_t i = 0;
for(i = 0; i < sizeof(s_cli_alarm_info)/sizeof(alarm_info_t); i++)
{
bk_alarm_register(id, &s_cli_alarm_info[i]);
}
}
static void aon_rtc_autotest_stop(aon_rtc_id_t id)
{
uint32_t i = 0;
for(i = 0; i < sizeof(s_cli_alarm_info)/sizeof(alarm_info_t); i++)
{
bk_alarm_unregister(id, s_cli_alarm_info[i].name);
}
}
static void cli_aon_rtc_auto_test_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
uint32_t aon_rtc_id;
if (argc != 3) {
cli_aon_rtc_help();
return;
}
aon_rtc_id = os_strtoul(argv[1], NULL, 10);
if (os_strcmp(argv[2], "start") == 0)
{
aon_rtc_autotest_start(aon_rtc_id);
}
else if (os_strcmp(argv[2], "stop") == 0)
{
aon_rtc_autotest_stop(aon_rtc_id);
}
else
cli_aon_rtc_help();
}
#if AON_RTC_DEBUG
static void cli_aon_rtc_timing_test_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
uint32_t aon_rtc_id;
uint32_t round, cnts, set_tick_val = 0xfffffff0;
if (argc != 5) {
cli_aon_rtc_help();
return;
}
aon_rtc_id = os_strtoul(argv[1], NULL, 10);
round = os_strtoul(argv[2], NULL, 10);
cnts = os_strtoul(argv[3], NULL, 10);
set_tick_val = os_strtoul(argv[4], NULL, 10);
bk_aon_rtc_timing_test(aon_rtc_id, round, cnts, set_tick_val);
}
#endif
static void cli_aon_rtc_dump_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
uint32_t aon_rtc_id;
if (argc != 2) {
cli_aon_rtc_help();
return;
}
aon_rtc_id = os_strtoul(argv[1], NULL, 10);
bk_aon_rtc_dump(aon_rtc_id);
}
#define AON_RTC_CMD_CNT (sizeof(s_aon_rtc_commands) / sizeof(struct cli_command))
static const struct cli_command s_aon_rtc_commands[] = {
{"aon_rtc_driver", "aon_rtc_driver {init|deinit}", cli_aon_rtc_driver_cmd},
{"aon_rtc_get_time", "aon_rtc_get_time {id}", cli_aon_rtc_get_time},
{"aon_rtc_register", "aon_rtc_register {id} {name} {period_tick} {period_cnt}, {callback}", cli_aon_rtc_register_cmd},
{"aon_rtc_unregister", "aon_rtc_unregister {id} {name}", cli_aon_rtc_unregister_cmd},
{"aon_rtc_auto_test", "{id} {start|stop}", cli_aon_rtc_auto_test_cmd},
#if AON_RTC_DEBUG
{"aon_rtc_timing_test", "{id} {rounds} {cycles} {set tick val}", cli_aon_rtc_timing_test_cmd},
#endif
{"aon_rtc_dump", "{id}", cli_aon_rtc_dump_cmd},
};
int cli_aon_rtc_init(void)
{
BK_LOG_ON_ERR(bk_aon_rtc_driver_init());
return cli_register_commands(s_aon_rtc_commands, AON_RTC_CMD_CNT);
}
+30
View File
@@ -0,0 +1,30 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bk_cli.h"
#include <common/sys_config.h>
#define BLE_CMD_CNT (sizeof(s_ble_commands) / sizeof(struct cli_command))
static const struct cli_command s_ble_commands[] = {
#if (CONFIG_BLE == 1)
{"ble", "ble arg1 arg2", ble_command},
#endif
};
int cli_ble_init(void)
{
return cli_register_commands(s_ble_commands, BLE_CMD_CNT);
}
@@ -0,0 +1,277 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <common/sys_config.h>
#ifdef __cplusplus
extern "C" {
#endif
#if (CONFIG_WIFI_ENABLE)
#define CLI_CFG_WIFI 1
#else
#define CLI_CFG_WIFI 0
#endif //#if (CONFIG_WIFI_ENABLE)
#define CLI_CFG_BLE 1
#if (CONFIG_BK_NETIF)
#define CLI_CFG_NETIF 1
#else
#define CLI_CFG_NETIF 0
#endif //#if (CONFIG_LWIP)
#define CLI_CFG_MISC 0
#define CLI_CFG_MEM 0
#if (CONFIG_WIFI_ENABLE)
#define CLI_CFG_PHY 0
#else
#define CLI_CFG_PHY 0
#endif //#if (CONFIG_WIFI_ENABLE)
#if (CONFIG_STA_PS)
#define CLI_CFG_PWR 0
#else
#define CLI_CFG_PWR 0
#endif
#define CLI_CFG_TIMER 0
#if CONFIG_INT_WDT
#define CLI_CFG_WDT 0
#endif
#if CONFIG_TRNG_SUPPORT
#define CLI_CFG_TRNG 0
#else
#define CLI_CFG_TRNG 0
#endif
#if CONFIG_EFUSE
#define CLI_CFG_EFUSE 0
#else
#define CLI_CFG_EFUSE 0
#endif
#define CLI_CFG_GPIO 0
#define CLI_CFG_OS 0
#if ((CONFIG_OTA_TFTP) || (CONFIG_OTA_HTTP))
#define CLI_CFG_OTA 0
#else
#define CLI_CFG_OTA 0
#endif
#if(CONFIG_KEYVALUE)
#define CLI_CFG_KEYVALUE 0
#else
#define CLI_CFG_KEYVALUE 0
#endif
#if(CONFIG_SUPPORT_MATTER)
#define CLI_CFG_MATTER 0
#else
#define CLI_CFG_MATTER 0
#endif
#define CLI_CFG_UART 0
#define CLI_CFG_ADC 0
#define CLI_CFG_SPI 0
#define CLI_CFG_MICO 0
#define CLI_CFG_REG 0
#define CLI_CFG_EXCEPTION 0
#if(CONFIG_GENERAL_DMA)
#define CLI_CFG_DMA 0
#else
#define CLI_CFG_DMA 0
#endif
#if(CONFIG_PWM)
#define CLI_CFG_PWM 0
#else
#define CLI_CFG_PWM 0
#endif
#if(CONFIG_FLASH)
#define CLI_CFG_FLASH 0
#else
#define CLI_CFG_FLASH 0
#endif
#if(CONFIG_SDIO_HOST)
#define CLI_CFG_SDIO_HOST 0
#else
#define CLI_CFG_SDIO_HOST 0
#endif
#if(CONFIG_ICU)
#define CLI_CFG_ICU 0
#else
#define CLI_CFG_ICU 0
#endif
#if CONFIG_I2C
#define CLI_CFG_I2C 0
#else
#define CLI_CFG_I2C 0
#endif
#if CONFIG_QSPI
#define CLI_CFG_QSPI 0
#else
#define CLI_CFG_QSPI 0
#endif
#if CONFIG_AON_RTC_TEST
#define CLI_CFG_AON_RTC 0
#else
#define CLI_CFG_AON_RTC 0
#endif
#if CONFIG_JPEG_ENCODE
#define CLI_CFG_JPEGENC 0
#else
#define CLI_CFG_JPEGENC 0
#endif
#if CONFIG_JPEG_DECODE
#define CLI_CFG_JPEGDEC 0
#else
#define CLI_CFG_JPEGDEC 0
#endif
#if CONFIG_CALENDAR
#define CLI_CFG_CALENDAR 0
#else
#define CLI_CFG_CALENDAR 0
#endif
//TODO default to 0
#define CLI_CFG_EVENT 0
#if (CONFIG_SOC_BK7251)
#define CLI_CFG_SECURITY 0
#else
#define CLI_CFG_SECURITY 0
#endif
#if CONFIG_TEMP_DETECT
#define CLI_CFG_TEMP_DETECT 0
#else
#define CLI_CFG_TEMP_DETECT 0
#endif
#if CONFIG_SDCARD_HOST
#define CLI_CFG_SD 0
#else
#define CLI_CFG_SD 0
#endif
#if CONFIG_FATFS
#define CLI_FATFS 0
#else
#define CLI_FATFS 0
#endif
#if CONFIG_AIRKISS_TEST
#define CLI_CFG_AIRKISS 0
#else
#define CLI_CFG_AIRKISS 0
#endif
#if CONFIG_IPERF_TEST
#define CLI_CFG_IPERF 0
#else
#define CLI_CFG_IPERF 0
#endif
#if (CONFIG_I2S)
#define CLI_CFG_I2S 0
#else
#define CLI_CFG_I2S 0
#endif
#if (CONFIG_SOC_BK7256XX)
#if CONFIG_DMA2D_TEST
#define CLI_CFG_DMA2D 0
#else
#define CLI_CFG_DMA2D 0
#endif
#if (CONFIG_AUDIO && CONFIG_DUAL_CORE && CONFIG_AUDIO_TEST && CONFIG_AUDIO_RISCV_IP_V1_0)
#define CLI_CFG_AUD 0
#endif
#if CONFIG_AUD_INTF_TEST
#define CLI_CFG_AUD_INTF 0
#endif
#if (CONFIG_SBC)
#define CLI_CFG_SBC 0
#endif
#if CONFIG_LCD_TEST
#define CLI_CFG_LCD 0
#else
#define CLI_CFG_LCD 0
#endif
#if (CONFIG_DUAL_CORE && CONFIG_AUDIO_TEST && !CONFIG_SLAVE_CORE)
#define CLI_CFG_AUD_CP0 0
#endif
#if (CONFIG_FFT_TEST)
#define CLI_CFG_FFT 0
#else
#define CLI_CFG_FFT 0
#endif
#endif
#if (CONFIG_AUDIO_AEC_TEST)
#define CLI_CFG_AEC 0
#endif
#if (CONFIG_AUDIO_G711_TEST)
#define CLI_CFG_G711 0
#endif
#if (CONFIG_AUDIO_MP3_TEST)
#define CLI_CFG_MP3 0
#endif
#if (CONFIG_SECURITYIP)
#define CLI_CFG_VAULT 0
#else
#define CLI_CFG_vault 0
#endif
#if ((CONFIG_SOC_BK7256XX || CONFIG_USB_UVC) && CONFIG_DUAL_CORE && CONFIG_PSRAM)
#define CLI_CFG_UVC 0
#else
#define CLI_CFG_UVC 0
#endif
#if ((CONFIG_CAMERA || CONFIG_SPIDMA) && CONFIG_APP_DEMO_VIDEO_TRANSFER)
#define CLI_CFG_DVP 0
#else
#define CLI_CFG_DVP 0
#endif
#if (CONFIG_PSRAM && !CONFIG_SLAVE_CORE)
#define CLI_CFG_PSRAM 0
#else
#define CLI_CFG_PSRAM 0
#endif
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,83 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <os/os.h>
#include "cli.h"
#include <driver/efuse.h>
static void cli_efuse_help(void)
{
CLI_LOGI("efuse_driver init\r\n");
CLI_LOGI("efuse_driver deinit\r\n");
CLI_LOGI("efuse_test write [addr] [data]\r\n");
CLI_LOGI("efuse_test read [addr]\r\n");
}
static void cli_efuse_driver_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
if (argc < 2) {
cli_efuse_help();
return;
}
if (os_strcmp(argv[1], "init") == 0) {
BK_LOG_ON_ERR(bk_efuse_driver_init());
CLI_LOGI("efuse driver init\n");
} else if (os_strcmp(argv[1], "deinit") == 0) {
BK_LOG_ON_ERR(bk_efuse_driver_deinit());
CLI_LOGI("efuse driver deinit\n");
} else {
cli_efuse_help();
return;
}
}
static void cli_efuse_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
if (argc < 2) {
cli_efuse_help();
return;
}
uint8_t addr, data;
if (os_strcmp(argv[1], "write") == 0) {
addr = os_strtoul(argv[2], NULL, 16);
data = os_strtoul(argv[3], NULL, 16);
BK_LOG_ON_ERR(bk_efuse_write_byte(addr, data));
CLI_LOGI("efuse write addr:0x%02x, data:0x%02x\r\n", addr, data);
} else if (os_strcmp(argv[1], "read") == 0) {
addr = os_strtoul(argv[2], NULL, 16);
data = 0;
BK_LOG_ON_ERR(bk_efuse_read_byte(addr, &data));
CLI_LOGI("efuse read addr:0x%02x, data:0x%02x\r\n", addr, data);
} else {
cli_efuse_help();
return;
}
}
#define EFUSE_CMD_CNT (sizeof(s_efuse_commands) / sizeof(struct cli_command))
static const struct cli_command s_efuse_commands[] = {
{"efuse_driver", "efuse_driver {init|deinit}", cli_efuse_driver_cmd},
{"efuse_test", "efuse_test {write|read}", cli_efuse_cmd}
};
int cli_efuse_init(void)
{
BK_LOG_ON_ERR(bk_efuse_driver_init());
return cli_register_commands(s_efuse_commands, EFUSE_CMD_CNT);
}
+109
View File
@@ -0,0 +1,109 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <driver/flash.h>
#include <driver/flash_partition.h>
#include "cli.h"
#include "flash_driver.h"
static void cli_flash_help(void)
{
CLI_LOGI("flash driver init\n");
CLI_LOGI("flash_driver deinit\n");
CLI_LOGI("flash {erase|write|read} [start_addr] [len]\n");
CLI_LOGI("flash_partition show\n");
}
static void cli_flash_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
if (argc < 2) {
cli_flash_help();
return;
}
uint32_t start_addr = os_strtoul(argv[2], NULL, 16);
uint32_t len = os_strtoul(argv[3], NULL, 10);
if (os_strcmp(argv[1], "erase") == 0) {
bk_flash_set_protect_type(FLASH_PROTECT_NONE);
for (uint32_t addr = start_addr; addr < (start_addr + len); addr += FLASH_SECTOR_SIZE) {
bk_flash_erase_sector(addr);
}
bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK);
} else if (os_strcmp(argv[1], "read") == 0) {
uint8_t buf[FLASH_PAGE_SIZE] = {0};
for (uint32_t addr = start_addr; addr < (start_addr + len); addr += FLASH_PAGE_SIZE) {
os_memset(buf, 0, FLASH_PAGE_SIZE);
bk_flash_read_bytes(addr, buf, FLASH_PAGE_SIZE);
CLI_LOGI("flash read addr:%x\r\n", addr);
CLI_LOGI("dump read flash data:\r\n");
for (uint32_t i = 0; i < 16; i++) {
for (uint32_t j = 0; j < 16; j++) {
os_printf("%02x ", buf[i * 16 + j]);
}
os_printf("\r\n");
}
}
} else if (os_strcmp(argv[1], "write") == 0) {
uint8_t buf[FLASH_PAGE_SIZE] = {0};
for (uint32_t i = 0; i < FLASH_PAGE_SIZE; i++) {
buf[i] = i;
}
bk_flash_set_protect_type(FLASH_PROTECT_NONE);
for (uint32_t addr = start_addr; addr < (start_addr + len); addr += FLASH_PAGE_SIZE) {
bk_flash_write_bytes(addr, buf, FLASH_PAGE_SIZE);
}
bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK);
} else if (os_strcmp(argv[1], "get_id") == 0) {
uint32_t flash_id = bk_flash_get_id();
CLI_LOGI("flash_id:%x\r\n", flash_id);
} else {
cli_flash_help();
}
}
static void cli_flash_partition_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
bk_logic_partition_t *partition;
if (os_strcmp(argv[1], "show") == 0) {
for (bk_partition_t par= BK_PARTITION_BOOTLOADER; par <= BK_PARTITION_MAX; par++) {
partition = bk_flash_partition_get_info(par);
if (partition == NULL)
continue;
CLI_LOGI("%4d | %11s | Dev:%d | 0x%08lx | 0x%08lx |\r\n", par,
partition->partition_description, partition->partition_owner,
partition->partition_start_addr, partition->partition_length);
}
} else {
cli_flash_help();
}
}
#define FLASH_CMD_CNT (sizeof(s_flash_commands) / sizeof(struct cli_command))
static const struct cli_command s_flash_commands[] = {
{"flash", "flash {erase|read|write} [start_addr] [len]", cli_flash_cmd},
{"flash_partition", "flash_partition {show}", cli_flash_partition_cmd},
};
int cli_flash_init(void)
{
BK_LOG_ON_ERR(bk_flash_driver_init());
return cli_register_commands(s_flash_commands, FLASH_CMD_CNT);
}
@@ -0,0 +1,508 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include "cli.h"
#include "driver/flash.h"
#include <driver/flash_partition.h>
#include "sys_driver.h"
#include "flash_bypass.h"
#include "flash.h"
#include <driver/psram.h>
#define TICK_PER_US 26
beken_thread_t idle_read_flash_handle = NULL;
beken_thread_t idle_read_psram_handle = NULL;
extern void delay_ms(UINT32 ms_count);
static bk_err_t test_flash_write(volatile uint32_t start_addr, uint32_t len)
{
uint32_t i;
u8 buf[256];
uint32_t addr = start_addr;
uint32_t length = len;
uint32_t tmp = addr + length;
for (i = 0; i < 256; i++)
buf[i] = i;
for (; addr < tmp; addr += 256) {
os_printf("write addr(size:256):%d\r\n", addr);
bk_flash_write_bytes(addr, (uint8_t *)buf, 256);
}
return kNoErr;
}
static bk_err_t test_flash_erase(volatile uint32_t start_addr, uint32_t len)
{
uint32_t addr = start_addr;
uint32_t length = len;
uint32_t tmp = addr + length;
for (; addr < tmp; addr += 0x1000) {
os_printf("erase addr:%d\r\n", addr);
bk_flash_erase_sector(addr);
}
return kNoErr;
}
static bk_err_t test_flash_read(volatile uint32_t start_addr, uint32_t len)
{
uint32_t i, j, tmp;
u8 buf[256];
uint32_t addr = start_addr;
uint32_t length = len;
tmp = addr + length;
for (; addr < tmp; addr += 256) {
os_memset(buf, 0, 256);
bk_flash_read_bytes(addr, (uint8_t *)buf, 256);
os_printf("read addr:%x\r\n", addr);
for (i = 0; i < 16; i++) {
for (j = 0; j < 16; j++)
os_printf("%02x ", buf[i * 16 + j]);
os_printf("\r\n");
}
}
return kNoErr;
}
static bk_err_t test_flash_read_without_print(volatile uint32_t start_addr, uint32_t len)
{
uint32_t tmp;
u8 buf[256];
uint32_t addr = start_addr;
uint32_t length = len;
tmp = addr + length;
for (; addr < tmp; addr += 256) {
os_memset(buf, 0, 256);
bk_flash_read_bytes(addr, (uint8_t *)buf, 256);
}
return kNoErr;
}
static bk_err_t test_flash_read_time(volatile uint32_t start_addr, uint32_t len)
{
UINT32 time_start, time_end;
uint32_t tmp;
u8 buf[256];
uint32_t addr = start_addr;
uint32_t length = len;
tmp = addr + length;
beken_time_get_time((beken_time_t *)&time_start);
os_printf("read time start:%d\r\n", time_start);
for (; addr < tmp; addr += 256) {
os_memset(buf, 0, 256);
bk_flash_read_bytes(addr, (uint8_t *)buf, 256);
}
beken_time_get_time((beken_time_t *)&time_end);
os_printf("read time end:%d\r\n", time_end);
os_printf("cost time:%d\r\n", time_end - time_start);
return kNoErr;
}
#if (CONFIG_SYSTEM_CTRL)
static bk_err_t test_flash_count_time(volatile uint32_t start_addr, uint32_t len, uint32_t test_times)
{
UINT32 time_start, time_end;
uint32_t tmp;
u8 buf[256];
uint32_t addr = start_addr;
uint32_t length = len;
extern u64 riscv_get_mtimer(void);
uint64_t start_tick, end_tick, tick_cnt = 0;
tmp = addr + length;
bk_flash_set_protect_type(FLASH_PROTECT_NONE);
beken_time_get_time((beken_time_t *)&time_start);
os_printf("----- FLASH COUNT TIME TEST BEGIN: start time:%d ms -----\r\n", time_start);
os_printf("===============================\r\n");
start_tick = riscv_get_mtimer();
for (addr = start_addr; addr < tmp; addr += 256) {
os_memset(buf, 0, 256);
bk_flash_read_bytes(addr, (uint8_t *)buf, 256);
}
end_tick = riscv_get_mtimer();
tick_cnt = end_tick - start_tick;
os_printf("[read 1 time] >>>>> cost tick time: %d us.\r\n", (uint32_t) (tick_cnt / TICK_PER_US));
os_printf("===============================\r\n");
start_tick = riscv_get_mtimer();
for (int i = 0; i < test_times; i++ ) {
for (addr = start_addr; addr < tmp; addr += 256) {
os_memset(buf, 0, 256);
bk_flash_read_bytes(addr, (uint8_t *)buf, 256);
}
}
end_tick = riscv_get_mtimer();
tick_cnt = end_tick - start_tick;
os_printf("[read %d time] >>>>> average tick time: %d us.\r\n", test_times, (uint32_t) (tick_cnt / TICK_PER_US / test_times));
os_printf("===============================\r\n");
start_tick = riscv_get_mtimer();
for (addr = start_addr; addr < tmp; addr += 0x1000) {
os_printf("erase addr:%d\r\n", addr);
bk_flash_erase_sector(addr);
}
end_tick = riscv_get_mtimer();
tick_cnt = end_tick - start_tick;
os_printf("[erase 1 time] >>>>> cost tick time: %d us.\r\n", (uint32_t) (tick_cnt / TICK_PER_US));
os_printf("===============================\r\n");
start_tick = riscv_get_mtimer();
for (int i = 0; i < test_times; i++ ) {
for (addr = start_addr; addr < tmp; addr += 0x1000) {
bk_flash_erase_sector(addr);
}
}
end_tick = riscv_get_mtimer();
tick_cnt = end_tick - start_tick;
os_printf("[erase %d time] >>>>> average tick time: %d us.\r\n", test_times, (uint32_t) (tick_cnt / TICK_PER_US / test_times));
os_printf("===============================\r\n");
start_tick = riscv_get_mtimer();
for (int i = 0; i < 256; i++)
buf[i] = i;
for (addr = start_addr; addr < tmp; addr += 256) {
bk_flash_write_bytes(addr, (uint8_t *)buf, 256);
}
end_tick = riscv_get_mtimer();
tick_cnt = end_tick - start_tick;
os_printf("[write 1 time] >>>>> cost tick time: %d us.\r\n", (uint32_t) (tick_cnt / TICK_PER_US));
os_printf("===============================\r\n");
start_tick = riscv_get_mtimer();
for (int i = 0; i < test_times; i++ ) {
for (addr = start_addr; addr < tmp; addr += 256) {
bk_flash_write_bytes(addr, (uint8_t *)buf, 256);
}
}
end_tick = riscv_get_mtimer();
tick_cnt = end_tick - start_tick;
os_printf("[write %d time] >>>>> average tick time: %d us.\r\n", test_times, (uint32_t) (tick_cnt / TICK_PER_US / test_times));
os_printf("===============================\r\n");
start_tick = riscv_get_mtimer();
bk_flash_set_protect_type(FLASH_PROTECT_NONE);
end_tick = riscv_get_mtimer();
tick_cnt = end_tick - start_tick;
os_printf("[enable security 1 time] >>>>> cost tick time: %d us.\r\n", (uint32_t)(tick_cnt / TICK_PER_US));
os_printf("===============================\r\n");
start_tick = riscv_get_mtimer();
for (int i = 0; i < test_times; i++ ) {
bk_flash_set_protect_type(FLASH_PROTECT_NONE);
}
end_tick = riscv_get_mtimer();
tick_cnt = end_tick - start_tick;
os_printf("[enable security %d time] >>>>> average tick time: %d us.\r\n", test_times, (uint32_t)(tick_cnt / TICK_PER_US / test_times));
os_printf("===============================\r\n");
start_tick = riscv_get_mtimer();
bk_flash_set_protect_type(FLASH_PROTECT_NONE);
bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK);
end_tick = riscv_get_mtimer();
tick_cnt = end_tick - start_tick;
os_printf("[en/dis security 1 time] >>>>> cost tick time: %d us.\r\n", (uint32_t) ((tick_cnt / TICK_PER_US)));
os_printf("===============================\r\n");
beken_time_get_time((beken_time_t *)&time_end);
os_printf("----- FLASH COUNT TIME TEST END: end time:%d ms -----\r\n", time_end);
os_printf("----- OVERALL TEST TIME:%d ms -----\r\n", time_end - time_start);
bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK);
return kNoErr;
}
#endif
static void test_idle_read_flash(void *arg) {
while (1) {
test_flash_read_without_print(0x1000, 1000);
test_flash_read_without_print(0x100000, 1000);
test_flash_read_without_print(0x200000, 1000);
test_flash_read_without_print(0x300000, 0x1000);
}
rtos_delete_thread(&idle_read_flash_handle);
}
#define write_data(addr,val) *((volatile unsigned long *)(addr)) = val
#define read_data(addr,val) val = *((volatile unsigned long *)(addr))
#define get_addr_data(addr) *((volatile unsigned long *)(addr))
#if (CONFIG_SYSTEM_CTRL && CONFIG_PSRAM)
static void test_idle_read_psram(void *arg) {
uint32_t i,val = 0;
uint32_t s0 = 0;
uint32_t s1 = 0;
uint32_t s2 = 0;
uint32_t s3 = 0;
os_printf("enter test_idle_read_psram\r\n");
bk_psram_init();
while (1) {
for(i=0;i<1024;i++){
write_data((0x60000000+i*0x4),0x11+i);
write_data((0x60001000+i*0x4),0x22+i);
write_data((0x60002000+i*0x4),0x33+i);
write_data((0x60003000+i*0x4),0x44+i);
}
for(i=0;i<1024;i++){
write_data((0x60004000+i*0x4),0x55+i);
write_data((0x60005000+i*0x4),0x66+i);
write_data((0x60006000+i*0x4),0x77+i);
write_data((0x60007000+i*0x4),0x88+i);
}
for(i=0;i<4*1024;i++){
val = get_addr_data(0x60000000+i*0x4);
s0 += val;
}
for(i=0;i<4*1024;i++){
val = get_addr_data(0x60004000+i*0x4);
s1 += val;
}
for(i=0;i<4*1024;i++){
val = get_addr_data(0x60000000+i*0x4);
s2 += val;
}
for(i=0;i<4*1024;i++){
val = get_addr_data(0x60004000+i*0x4);
s3 += val;
}
}
rtos_delete_thread(&idle_read_psram_handle);
}
#endif
static void flash_command_test(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
char cmd = 0;
uint32_t len = 0;
uint32_t addr = 0;
#if (CONFIG_SYSTEM_CTRL)
if (os_strcmp(argv[1], "config") == 0) {
uint32_t flash_src_clk = os_strtoul(argv[2], NULL, 10);
uint32_t flash_div_clk = os_strtoul(argv[3], NULL, 10);
uint32_t flash_line_mode = os_strtoul(argv[4], NULL, 10);
if (FLASH_CLK_XTAL == flash_src_clk) {
sys_drv_flash_cksel(flash_src_clk);
}
if((FLASH_CLK_XTAL != sys_drv_flash_get_clk_sel()) && (0 == flash_div_clk)) {
os_printf("Config fail. Please set src clk as 26M, or set div larger than 0 firstly.\n");
return;
}
sys_drv_flash_set_clk_div(flash_div_clk);
sys_drv_flash_cksel(flash_src_clk);
bk_flash_set_line_mode(flash_line_mode);
os_printf("flash_src_clk = %u. [0 -> 26M; 1->98M; 2-> 120M]\n", flash_src_clk);
os_printf("flash_div_clk = %u. \n", flash_div_clk);
os_printf("flash_line_mode = %u. \n", flash_line_mode);
return;
}
if (os_strcmp(argv[1], "qe") == 0) {
uint32_t param = 0;
uint32_t quad_enable = os_strtoul(argv[2], NULL, 10);
uint32_t delay_cycle1 = os_strtoul(argv[3], NULL, 10);
uint32_t delay_cycle2 = os_strtoul(argv[4], NULL, 10);
for(int i = 0; i< 20; i++) {
bk_flash_set_line_mode(2);
flash_bypass_quad_test(quad_enable, delay_cycle1, delay_cycle2);
while (REG_READ(REG_FLASH_OPERATE_SW) & BUSY_SW);
param = bk_flash_read_status_reg();
if (quad_enable) {
if(param & 0x200){
break;
} else {
os_printf("retry quad test, i = %d, flash status: 0x%x.\n", i, param);
}
} else {
if(param & 0x200){
os_printf("retry quad test, i = %d, flash status: 0x%x.\n", i, param);
} else {
break;
}
}
}
if (quad_enable) {
if(param & 0x200){
os_printf("flash quad enable success, flash status: 0x%x.\n", param);
} else {
os_printf("flash quad enable fail, flash status: 0x%x.\n", param);
}
} else {
if(param & 0x200){
os_printf("flash quad disable fail, flash status: 0x%x.\n", param);
} else {
os_printf("flash quad disable success, flash status: 0x%x.\n", param);
}
}
return;
}
#endif
if (os_strcmp(argv[1], "idle_read_start") == 0) {
uint32_t task_prio = os_strtoul(argv[2], NULL, 10);
os_printf("idle_read_flash task start: task_prio = %u.\n", task_prio);
rtos_create_thread(&idle_read_flash_handle, task_prio,
"idle_read_flash",
(beken_thread_function_t) test_idle_read_flash,
CONFIG_APP_MAIN_TASK_STACK_SIZE,
(beken_thread_arg_t)0);
return;
} else if (os_strcmp(argv[1], "idle_read_stop") == 0) {
if (idle_read_flash_handle) {
rtos_delete_thread(&idle_read_flash_handle);
idle_read_flash_handle = NULL;
os_printf("idle_read_flash task stop\n");
}
return;
}
#if (CONFIG_SYSTEM_CTRL && CONFIG_PSRAM)
if (os_strcmp(argv[1], "idle_read_psram_start") == 0) {
uint32_t task_prio = os_strtoul(argv[2], NULL, 10);
os_printf("idle_read_psram task start: task_prio = %u.\n", task_prio);
rtos_create_thread(&idle_read_psram_handle, task_prio,
"idle_read_psram",
(beken_thread_function_t) test_idle_read_psram,
CONFIG_APP_MAIN_TASK_STACK_SIZE,
(beken_thread_arg_t)0);
return;
} else if (os_strcmp(argv[1], "idle_read_psram_stop") == 0) {
if (idle_read_psram_handle) {
rtos_delete_thread(&idle_read_psram_handle);
idle_read_psram_handle = NULL;
os_printf("idle_read_psram task stop\n");
}
return;
}
#endif
if (os_strcmp(argv[1], "U") == 0) {
bk_flash_set_protect_type(FLASH_PROTECT_NONE);
return;
} else if (os_strcmp(argv[1], "P") == 0) {
bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK);
return;
} else if (os_strcmp(argv[1], "RSR") == 0) {
uint16_t sts_val = bk_flash_read_status_reg();
os_printf("read sts_val = 0x%x\n", sts_val);
return;
} else if (os_strcmp(argv[1], "WSR") == 0) {
uint16_t sts_val = os_strtoul(argv[2], NULL, 16);
bk_flash_write_status_reg(sts_val);
return;
} else if (os_strcmp(argv[1], "C") == 0) {
#if (CONFIG_SYSTEM_CTRL)
addr = atoi(argv[2]);
len = atoi(argv[3]);
uint32_t test_times = os_strtoul(argv[4], NULL, 10);
test_flash_count_time(addr, len, test_times);
#endif
return;
}
if (argc == 4) {
cmd = argv[1][0];
addr = atoi(argv[2]);
len = atoi(argv[3]);
switch (cmd) {
case 'E':
bk_flash_set_protect_type(FLASH_PROTECT_NONE);
test_flash_erase(addr, len);
bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK);
break;
case 'R':
test_flash_read(addr, len);
break;
case 'W':
bk_flash_set_protect_type(FLASH_PROTECT_NONE);
test_flash_write(addr, len);
bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK);
break;
//to check whether protection mechanism can work
case 'N':
test_flash_erase(addr, len);
break;
case 'M':
test_flash_write(addr, len);
break;
case 'T':
test_flash_read_time(addr, len);
break;
default:
break;
}
} else
os_printf("FLASH <R/W/E/M/N/T> <start_addr> <len>\r\n");
}
static void partShow_Command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
bk_partition_t i;
bk_logic_partition_t *partition;
for (i = BK_PARTITION_BOOTLOADER; i <= BK_PARTITION_MAX; i++) {
partition = bk_flash_partition_get_info(i);
if (partition == NULL)
continue;
os_printf("%4d | %11s | Dev:%d | 0x%08lx | 0x%08lx |\r\n", i,
partition->partition_description, partition->partition_owner,
partition->partition_start_addr, partition->partition_length);
};
}
#define FLASH_CMD_CNT (sizeof(s_flash_commands) / sizeof(struct cli_command))
static const struct cli_command s_flash_commands[] = {
{"fmap_test", "flash_test memory map", partShow_Command},
{"flash_test", "flash_test <cmd(R/W/E/N)>", flash_command_test},
};
int cli_flash_test_init(void)
{
return cli_register_commands(s_flash_commands, FLASH_CMD_CNT);
}
File diff suppressed because it is too large Load Diff
+241
View File
@@ -0,0 +1,241 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bk_cli.h"
#include "wlan_defs_pub.h"
#include "bk_private/bk_wifi_wrapper.h"
#if CONFIG_LWIP
#if CONFIG_HARMONY_LWIP
//#include "ping.h"
#else
#include "lwip/ping.h"
#endif
#endif
#include <components/netif.h>
#include "cli.h"
extern void make_tcp_server_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
#define CLI_DUMP_IP(_prompt, _ifx, _cfg) do {\
CLI_LOGI("%s netif(%s) ip4=%s mask=%s gate=%s dns=%s\n", (_prompt),\
(_ifx) == NETIF_IF_STA ? "sta" : "ap",\
(_cfg)->ip, (_cfg)->mask, (_cfg)->gateway, (_cfg)->dns);\
} while(0)
#if (CLI_CFG_NETIF == 1)
static void ip_cmd_show_ip(int ifx)
{
netif_ip4_config_t config;
if (ifx == NETIF_IF_STA || ifx == NETIF_IF_AP) {
BK_LOG_ON_ERR(bk_netif_get_ip4_config(ifx, &config));
CLI_DUMP_IP(" ", ifx, &config);
} else {
BK_LOG_ON_ERR(bk_netif_get_ip4_config(NETIF_IF_STA, &config));
CLI_DUMP_IP(" ", NETIF_IF_STA, &config);
BK_LOG_ON_ERR(bk_netif_get_ip4_config(NETIF_IF_AP, &config));
CLI_DUMP_IP(" ", NETIF_IF_AP, &config);
}
}
void cli_ip_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
netif_ip4_config_t config = {0};
int ifx = NETIF_IF_COUNT;
if (argc > 1) {
if (os_strcmp("sta", argv[1]) == 0) {
ifx = NETIF_IF_STA;
} else if (os_strcmp("ap", argv[1]) == 0) {
ifx = NETIF_IF_AP;
} else {
CLI_LOGE("invalid netif name\n");
return;
}
}
if (argc == 1) {
ip_cmd_show_ip(NETIF_IF_COUNT);
} else if (argc == 2) {
ip_cmd_show_ip(ifx);
} else if (argc == 6) {
os_strncpy(config.ip, argv[2], NETIF_IP4_STR_LEN);
os_strncpy(config.mask, argv[3], NETIF_IP4_STR_LEN);
os_strncpy(config.gateway, argv[4], NETIF_IP4_STR_LEN);
os_strncpy(config.dns, argv[5], NETIF_IP4_STR_LEN);
BK_LOG_ON_ERR(bk_netif_set_ip4_config(ifx, &config));
CLI_DUMP_IP("set static ip, ", ifx, &config);
} else {
CLI_LOGE("usage: ip [sta|ap][{ip}{mask}{gate}{dns}]\n");
}
}
#if CONFIG_IPV6
static void ip6_cmd_show_ip(int ifx)
{
if (ifx == NETIF_IF_STA || ifx == NETIF_IF_AP) {
bk_netif_get_ip6_addr_info(ifx);
} else {
CLI_LOGI("[sta]\n");
bk_netif_get_ip6_addr_info(NETIF_IF_STA);
CLI_LOGI("[ap]\n");
bk_netif_get_ip6_addr_info(NETIF_IF_AP);
}
}
void cli_ip6_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
int ifx = NETIF_IF_COUNT;
if (argc > 1) {
if (os_strcmp("sta", argv[1]) == 0) {
ifx = NETIF_IF_STA;
} else if (os_strcmp("ap", argv[1]) == 0) {
ifx = NETIF_IF_AP;
} else {
CLI_LOGE("invalid netif name\n");
return;
}
}
if (argc == 1) {
ip6_cmd_show_ip(NETIF_IF_COUNT);
} else if (argc == 2) {
ip6_cmd_show_ip(ifx);
}
}
#endif
void cli_dhcpc_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
BK_LOG_ON_ERR(bk_netif_dhcpc_start(NETIF_IF_STA));
CLI_LOGI("STA start dhcp client\n");
}
void arp_Command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
os_printf("arp_Command\r\n");
}
void cli_ping_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
#if 0 //CONFIG_LWIP
uint32_t cnt = 4;
if (argc == 1) {
os_printf("Please input: ping <host address>\n");
return;
}
if (argc == 2 && (os_strcmp("--stop", argv[1]) == 0)) {
ping_stop();
return;
}
if (argc > 2)
cnt = os_strtoul(argv[2], NULL, 10);
os_printf("ping IP address:%s\n", argv[1]);
ping_start(argv[1], cnt, 0);
#endif
}
#if CONFIG_ALI_MQTT
extern void test_mqtt_start(const char *host_name, const char *username,
const char *password, const char *topic);
void cli_ali_mqtt_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
os_printf("start test mqtt...\n");
if (argc == 4) {
test_mqtt_start(argv[1], argv[2], argv[3], NULL);
} else if (argc == 5) {
test_mqtt_start(argv[1], argv[2], argv[3], argv[4]);
} else {
// mqttali 222.71.10.2 aclsemi ****** /aclsemi/bk7256/cmd/1234
CLI_LOGE("usage: mqttali [host name|ip] [username] [password] [topic]\n");
}
}
#endif
#if CONFIG_HTTP
extern void LITE_openlog(const char *ident);
extern void LITE_closelog(void);
void cli_http_debug_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
uint32 http_log = 0;
if (argc == 2) {
http_log = os_strtoul(argv[1], NULL, 10);
if (1 == http_log ) {
LITE_openlog("http");
} else {
LITE_closelog();
}
} else {
CLI_LOGE("usage: httplog [1|0].\n");
}
}
#endif
uint32_t g_per_packet_info_output_bitmap = 0;
void set_per_packet_info_output_bitmap(const char *bitmap)
{
g_per_packet_info_output_bitmap = os_strtoul(bitmap, NULL, 16);
CLI_LOGI("set per_packet_info_output_bitmap:0x%x\n",g_per_packet_info_output_bitmap);
}
void cli_per_packet_info_output_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
if (argc == 2) {
set_per_packet_info_output_bitmap(argv[1]);
} else {
CLI_LOGE("usage: per_packet_info [per_packet_info_output_bitmap(base 16)]\n");
}
}
#define NETIF_CMD_CNT (sizeof(s_netif_commands) / sizeof(struct cli_command))
static const struct cli_command s_netif_commands[] = {
{"ip", "ip [sta|ap][{ip}{mask}{gate}{dns}]", cli_ip_cmd},
{"dhcpc", "dhcpc", cli_dhcpc_cmd},
{"ping", "ping <ip>", cli_ping_cmd},
#ifdef CONFIG_IPV6
{"ping6", "ping6 xxx", cli_ping_cmd},
{"ip6", "ip6 [sta|ap][{ip}{state}]", cli_ip6_cmd},
#endif
#ifdef TCP_CLIENT_DEMO
{"tcp_cont", "tcp_cont [ip] [port]", tcp_make_connect_server_command},
#endif
#if CONFIG_TCP_SERVER_TEST
{"tcp_server", "tcp_server [ip] [port]", make_tcp_server_command },
#endif
#if CONFIG_ALI_MQTT
{"mqttali", "paho mqtt test", cli_ali_mqtt_cmd},
#endif
#if CONFIG_OTA_HTTP
{"httplog", "httplog [1|0].", cli_http_debug_cmd},
#endif
{"per_packet_info", "per_packet_info [per_packet_info_output_bitmap(base 16)]", cli_per_packet_info_output_cmd},
};
int cli_netif_init(void)
{
return cli_register_commands(s_netif_commands, NETIF_CMD_CNT);
}
#endif //#if (CLI_CFG_NETIF == 1)
+270
View File
@@ -0,0 +1,270 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "cli.h"
#include <components/system.h>
#include <os/str.h>
#include "icu_hal.h"
#include "pwm_hal.h"
#include "timer_hal.h"
#include "gpio_hal.h"
#include "dma_hal.h"
#include "uart_hal.h"
#include "wdt_hal.h"
#include "trng_hal.h"
#include "efuse_hal.h"
#include "adc_hal.h"
#include "spi_hal.h"
#include "i2c_hal.h"
#if CONFIG_QSPI
#include "qspi_hal.h"
#endif
#if CONFIG_AON_RTC
#include "aon_rtc_hal.h"
#endif
#if CONFIG_CALENDAR
#include "calendar_hal.h"
#endif
#if CONFIG_FLASH
#include "flash_hal.h"
#endif
#if CONFIG_SDIO_HOST
#include "sdio_host_hal.h"
#endif
static int hex2num(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
return -1;
}
static int hex2byte(const char *hex)
{
int a, b;
a = hex2num(*hex++);
if (a < 0)
return -1;
b = hex2num(*hex++);
if (b < 0)
return -1;
return (a << 4) | b;
}
/**
* hexstr2bin - Convert ASCII hex string into binary data
* @hex: ASCII hex string (e.g., "01ab")
* @buf: Buffer for the binary data
* @len: Length of the text to convert in bytes (of buf); hex will be double
* this size
* Returns: 0 on success, -1 on failure (invalid hex string)
*/
static int cli_hexstr2bin(const char *hex, u8 *buf, size_t len)
{
size_t i;
int a;
const char *ipos = hex;
u8 *opos = buf;
for (i = 0; i < len; i++) {
a = hex2byte(ipos);
if (a < 0)
return -1;
*opos++ = a;
ipos += 2;
}
return 0;
}
#if CONFIG_JPEG_ENCODE
#include "jpeg_hal.h"
#endif
static void cli_reg_write_read_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
UINT32 reg_addr = 0, reg_value = 0;
UINT8 optr_len = 0, optr_tab[9];
os_memset(optr_tab, 0, 9);
os_memset(optr_tab, 0x30, 8);
if (os_strncmp(argv[1], "-r", 2) == 0) {
if (argc != 3) {
os_printf("regshow -r addr\r\n");
return;
}
optr_len = os_strlen(argv[2]);
if (optr_len > 8) {
os_printf("addr 0-FFFFFFFF\r\n");
return;
}
optr_len = 8 - optr_len;
os_memcpy(&optr_tab[optr_len], argv[2], os_strlen(argv[2]));
cli_hexstr2bin((char *)optr_tab, (u8 *)&reg_addr, 4);
reg_addr = ntohl(reg_addr);
os_printf("regshow R: addr:0x%08x, value:0x%08x\r\n", reg_addr, REG_READ(reg_addr));
} else if (os_strncmp(argv[1], "-w", 2) == 0) {
if (argc != 4) {
os_printf("regshow -w addr value\r\n");
return;
}
optr_len = os_strlen(argv[2]);
if (optr_len > 8) {
os_printf("addr 0-FFFFFFFF\r\n");
return;
}
optr_len = 8 - optr_len;
os_memcpy(&optr_tab[optr_len], argv[2], os_strlen(argv[2]));
cli_hexstr2bin((char *)optr_tab, (u8 *)&reg_addr, 4);
reg_addr = ntohl(reg_addr);
os_memset(optr_tab, 0x30, 8);
optr_len = os_strlen(argv[3]);
if (optr_len > 8) {
os_printf("value 0-FFFFFFFF\r\n");
return;
}
optr_len = 8 - optr_len;
os_memcpy(&optr_tab[optr_len], argv[3], os_strlen(argv[3]));
cli_hexstr2bin((char *)optr_tab, (u8 *)&reg_value, 4);
reg_value = ntohl(reg_value);
REG_WRITE(reg_addr, reg_value);
#if (CLI_CFG_WIFI == 1)
extern INT32 rwnx_cal_save_trx_rcbekn_reg_val(void);
// when write trx and rc beken regs, updata registers save.
if ((reg_addr & 0xfff0000) == 0x1050000)
rwnx_cal_save_trx_rcbekn_reg_val();
#endif
os_printf("regshow W: addr:0x%08x, value:0x%08x - check:0x%08x\r\n",
reg_addr, reg_value, REG_READ(reg_addr));
} else
os_printf("regshow -w/r addr [value]\r\n");
}
static void cli_reg_dump_help(void)
{
CLI_LOGI("regdump icu\n");
CLI_LOGI(" pwm\n");
CLI_LOGI(" gpio [index]\n");
CLI_LOGI(" timer\n");
CLI_LOGI(" dma [channel]\n");
CLI_LOGI(" uart id\n");
CLI_LOGI(" wdt\n");
CLI_LOGI(" trng\n");
CLI_LOGI(" efuse\n");
CLI_LOGI(" adc\n");
CLI_LOGI(" spi\n");
}
static void cli_reg_dump_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
uint8_t index = os_strtoul(argv[2], NULL, 10);
if (argc == 1) {
cli_reg_dump_help();
return;
}
if (os_strcmp(argv[1], "icu") == 0) {
#if (CONFIG_ICU)
icu_struct_dump();
#endif
} else if (os_strcmp(argv[1], "pwm") == 0) {
pwm_struct_dump();
} else if (os_strcmp(argv[1], "timer") == 0) {
timer_struct_dump();
} else if (os_strcmp(argv[1], "gpio") == 0) {
gpio_struct_dump(index);
} else if (os_strcmp(argv[1], "dma") == 0) {
dma_struct_dump(index);
} else if (os_strcmp(argv[1], "uart") == 0) {
uart_struct_dump(index);
} else if (os_strcmp(argv[1], "wdt") == 0) {
wdt_struct_dump();
} else if (os_strcmp(argv[1], "trng") == 0) {
#if (CONFIG_TRNG_SUPPORT)
trng_struct_dump();
#endif
} else if (os_strcmp(argv[1], "efuse") == 0) {
#if (CONFIG_EFUSE)
efuse_struct_dump();
#endif
} else if (os_strcmp(argv[1], "adc") == 0) {
adc_struct_dump();
} else if (os_strcmp(argv[1], "spi") == 0) {
spi_struct_dump(index);
} else if (os_strcmp(argv[1], "i2c") == 0) {
i2c_struct_dump(index);
}
#if CONFIG_QSPI
else if (os_strcmp(argv[1], "qspi") == 0) {
qspi_struct_dump();
}
#endif
#if CONFIG_AON_RTC
else if (os_strcmp(argv[1], "aon_rtc") == 0) {
aon_rtc_struct_dump();
}
#endif
#if CONFIG_JPEG_ENCODE
else if (os_strcmp(argv[1], "jpeg") == 0) {
jpeg_struct_dump();
}
#endif
#if CONFIG_CALENDAR
else if (os_strcmp(argv[1], "calendar") == 0) {
calendar_struct_dump();
}
#endif
#if CONFIG_FLASH
else if (os_strcmp(argv[1], "flash") == 0) {
flash_struct_dump();
}
#endif
#if CONFIG_SDIO_HOST
else if (os_strcmp(argv[1], "sdio_host") == 0) {
sdio_host_struct_dump();
}
#endif
else {
cli_reg_dump_help();
return;
}
}
#define REG_CMD_CNT (sizeof(s_reg_commands) / sizeof(struct cli_command))
static const struct cli_command s_reg_commands[] = {
{"regshow", "regshow -w/r addr [value]", cli_reg_write_read_cmd},
{"regdump", "regdump {module}", cli_reg_dump_cmd},
};
int cli_reg_init(void)
{
return cli_register_commands(s_reg_commands, REG_CMD_CNT);
}
+321
View File
@@ -0,0 +1,321 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include "sys_rtos.h"
#include <os/os.h>
#include <common/bk_kernel_err.h>
#include "bk_cli.h"
#include "stdarg.h"
#include <common/bk_include.h>
#include <os/mem.h>
#include <os/str.h>
#include "bk_phy.h"
#include "cli.h"
#include "cli_config.h"
#include <components/log.h>
#include <driver/uart.h>
#include "bk_rtos_debug.h"
#if CONFIG_SHELL_ASYNCLOG
#include "components/shell_task.h"
#endif
#include "bk_api_cli.h"
#include "boot.h"
static void debug_help_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
#if CONFIG_DUAL_CORE
#include "mb_ipc_cmd.h"
#include <driver/gpio.h>
#include "amp_lock_api.h"
static void debug_ipc_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
static void debug_rpc_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
static void debug_rpc_gpio_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
static void debug_cpulock_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
static u8 ipc_inited = 0;
static u8 rpc_inited = 0;
#endif
#if CONFIG_ARCH_RISCV
static void debug_perfmon_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
static void debug_show_boot_time(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
#endif
const struct cli_command debug_cmds[] = {
{"help", "list debug cmds", debug_help_command},
#if CONFIG_DUAL_CORE
{"ipc", "ipc", debug_ipc_command},
{"rpc", "rpc", debug_rpc_command},
{"gpio_out", "gpio_out gpio_id {0|1}", debug_rpc_gpio_command},
{"cpu_lock", "cpu_lock [timeout 1~20]", debug_cpulock_command},
#endif
#if CONFIG_ARCH_RISCV
{"perfmon", "perfmon(calc MIPS)", debug_perfmon_command},
{"boottime", "boottime(show boot mtime info)", debug_show_boot_time},
#endif
};
const int cli_debug_table_size = ARRAY_SIZE(debug_cmds);
void print_cmd_table(const struct cli_command *cmd_table, int table_items)
{
int i;
for (i = 0; i < table_items; i++)
{
if (cmd_table[i].name)
{
if (cmd_table[i].help)
os_printf("%s: %s\r\n", cmd_table[i].name, cmd_table[i].help);
else
os_printf("%s\r\n", cmd_table[i].name);
}
}
}
void print_cmd_help(const struct cli_command *cmd_table, int table_items, void *func)
{
int i;
for (i = 0; i < table_items; i++)
{
if(cmd_table[i].function == func)
{
if (cmd_table[i].help)
os_printf("%s\r\n", cmd_table[i].help);
break;
}
}
}
static void debug_help_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
os_printf("====Debug Commands====\r\n");
print_cmd_table(debug_cmds, ARRAY_SIZE(debug_cmds));
}
#if CONFIG_DUAL_CORE
static void print_debug_cmd_help(void *func)
{
print_cmd_help(debug_cmds, ARRAY_SIZE(debug_cmds), func);
}
static void debug_rpc_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
int ret_val;
if(rpc_inited)
{
os_printf("rpc started\r\n");
return;
}
ret_val = rpc_init();
os_printf("rpc init: %d\r\n", ret_val);
rpc_inited = 1;
#if CONFIG_MASTER_CORE
if(ipc_inited)
{
ret_val = ipc_send_test_cmd(0x12);
os_printf("ipc server test: ret=%d\r\n", ret_val);
ret_val = ipc_send_get_ps_flag();
os_printf("ipc server ps: ret= 0x%x\r\n", ret_val);
ret_val = ipc_send_get_heart_rate();
os_printf("ipc server hr: ret= 0x%x\r\n", ret_val);
ret_val = ipc_send_set_heart_rate(0x33);
os_printf("ipc server set hr: ret= %d\r\n", ret_val);
}
#endif
}
static void debug_ipc_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
int ret_val;
if(ipc_inited)
{
os_printf("ipc started\r\n");
return;
}
ret_val = ipc_init();
os_printf("ipc init: %d\r\n", ret_val);
ipc_inited = 1;
#if CONFIG_SLAVE_CORE
ret_val = ipc_send_power_up();
os_printf("ipc client power: %d\r\n", ret_val);
ret_val = ipc_send_heart_beat(0x34);
os_printf("ipc client heartbeat: %d\r\n", ret_val);
ret_val = ipc_send_test_cmd(0x12);
os_printf("ipc client test: %d\r\n", ret_val);
#endif
}
extern bk_err_t bk_gpio_enable_output_rpc(gpio_id_t gpio_id);
extern bk_err_t bk_gpio_set_output_high_rpc(gpio_id_t gpio_id);
extern bk_err_t bk_gpio_set_output_low_rpc(gpio_id_t gpio_id);
static void debug_rpc_gpio_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
#if CONFIG_SLAVE_CORE
int ret_val;
u32 gpio_id = 0;
u32 level = 0;
if (argc < 3)
{
print_debug_cmd_help(debug_rpc_gpio_command);
return;
}
gpio_id = strtoul(argv[1], NULL, 0);
level = strtoul(argv[2], NULL, 0);
ret_val = bk_gpio_enable_output_rpc(gpio_id);
os_printf("rpc gpio:ret=%d\r\n", ret_val);
if(level)
ret_val = bk_gpio_set_output_high_rpc(gpio_id);
else
ret_val = bk_gpio_set_output_low_rpc(gpio_id);
os_printf("rpc gpio:ret=%d\r\n", ret_val);
#endif
}
static void debug_cpulock_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
u32 timeout_second = 10; // 10s
if(ipc_inited == 0)
{
os_printf("Failed: no ipc client/server in CPU0/CPU1.\r\n");
return;
}
if (argc > 1)
{
timeout_second = strtoul(argv[1], NULL, 0);
if(timeout_second > 20)
timeout_second = 20;
if(timeout_second == 0)
timeout_second = 10;
}
else
{
print_debug_cmd_help(debug_cpulock_command);
os_printf("default timeout 10s is used.\r\n");
}
int ret_val = BK_FAIL;
ret_val = amp_res_init(AMP_RES_ID_GPIO);
os_printf("amp res init:ret=%d\r\n", ret_val);
ret_val = amp_res_acquire(AMP_RES_ID_GPIO, timeout_second * 1000);
os_printf("amp res acquire:ret=%d\r\n", ret_val);
rtos_delay_milliseconds(timeout_second * 1000);
if(ret_val == 0)
{
ret_val = amp_res_release(AMP_RES_ID_GPIO);
os_printf("amp res release:ret=%d\r\n", ret_val);
}
else
{
os_printf("amp res release: no release\r\n");
}
}
#endif
const struct cli_command * cli_debug_cmd_table(int *num)
{
*num = ARRAY_SIZE(debug_cmds);
return &debug_cmds[0];
}
#if CONFIG_ARCH_RISCV
extern u64 riscv_get_instruct_cnt(void);
extern u64 riscv_get_mtimer(void);
static u64 saved_time = 0;
static u64 saved_inst_cnt = 0;
static void debug_perfmon_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
u64 cur_time = riscv_get_mtimer();
u64 cur_inst_cnt = riscv_get_instruct_cnt();
os_printf("cur time: %x:%08x\r\n", (u32)(cur_time >> 32), (u32)(cur_time & 0xFFFFFFFF));
os_printf("cur inst_cnt: %x:%08x\r\n", (u32)(cur_inst_cnt >> 32), (u32)(cur_inst_cnt & 0xFFFFFFFF));
saved_time = (cur_time - saved_time) / 26;
saved_inst_cnt = cur_inst_cnt - saved_inst_cnt;
// os_printf("elapse time(us): %x:%08x\r\n", (u32)(saved_time >> 32), (u32)(saved_time & 0xFFFFFFFF));
// os_printf("diff inst_cnt: %x:%08x\r\n", (u32)(saved_inst_cnt >> 32), (u32)(saved_inst_cnt & 0xFFFFFFFF));
os_printf("MIPS: %d KIPS\r\n", (u32)(saved_inst_cnt * 1000 / saved_time));
saved_time = cur_time;
saved_inst_cnt = cur_inst_cnt;
}
static void debug_show_boot_time(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
u64 cur_time = riscv_get_mtimer();
u64 cur_inst_cnt = riscv_get_instruct_cnt();
BK_LOGI("debug","cur time: %x:%08x\r\n", (u32)(cur_time >> 32), (u32)(cur_time & 0xFFFFFFFF));
BK_LOGI("debug","cur time: %ldms\r\n", (u32)(cur_time/26000));
BK_LOGI("debug","cur inst_cnt: %x:%08x\r\n", (u32)(cur_inst_cnt >> 32), (u32)(cur_inst_cnt & 0xFFFFFFFF));
#if CONFIG_SAVE_BOOT_TIME_POINT
show_saved_mtime_info();
#endif
}
#endif
+405
View File
@@ -0,0 +1,405 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <os/os.h>
#include "cli.h"
#include <driver/uart.h>
#include <driver/trng.h>
#include "uart_statis.h"
#include "bk_misc.h"
#define CLI_UART_RECV_BUF_LEN 1024
static void cli_uart_help(void)
{
CLI_LOGI("uart_driver init\n");
CLI_LOGI("uart_driver deinit\n");
CLI_LOGI("uart_int {id} {enable|disable|reg} {tx|rx}\n");
CLI_LOGI("uart {id} {init|deinit|write|read|write_string|dump_statis} [...]\n");
CLI_LOGI("uart_test {idle_start|idle_stop} {uart1|uart2|uart3}\n");
}
static void cli_uart_driver_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
if (argc < 2) {
cli_uart_help();
return;
}
if (os_strcmp(argv[1], "init") == 0) {
BK_LOG_ON_ERR(bk_uart_driver_init());
CLI_LOGI("uart driver init\n");
} else if (os_strcmp(argv[1], "deinit") == 0) {
BK_LOG_ON_ERR(bk_uart_driver_deinit());
CLI_LOGI("uart driver deinit\n");
} else {
cli_uart_help();
return;
}
}
static void cli_uart_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
uint32_t uart_id;
if (argc < 2) {
cli_uart_help();
return;
}
uart_id = os_strtoul(argv[1], NULL, 10);
if (os_strcmp(argv[2], "init") == 0) {
CLI_RET_ON_INVALID_ARGC(argc, 5);
uart_config_t config = {0};
os_memset(&config, 0, sizeof(uart_config_t));
config.baud_rate = os_strtoul(argv[3], NULL, 10);
config.data_bits = os_strtoul(argv[4], NULL, 10);
config.parity = os_strtoul(argv[5], NULL, 10);
config.stop_bits = os_strtoul(argv[6], NULL, 10);
if (argc > 7) {
config.flow_ctrl = os_strtoul(argv[7], NULL, 10);
}
if (argc > 8) {
config.src_clk = os_strtoul(argv[8], NULL, 10);
}
BK_LOG_ON_ERR(bk_uart_init(uart_id, &config));
CLI_LOGI("uart init, uart_id=%d\n", uart_id);
} else if (os_strcmp(argv[2], "deinit") == 0) {
BK_LOG_ON_ERR(bk_uart_deinit(uart_id));
CLI_LOGI("uart deinit, uart_id=%d\n", uart_id);
} else if (os_strcmp(argv[2], "write") == 0) {
uint32_t buf_len = os_strtoul(argv[3], NULL, 10);
uint8_t *send_data = (uint8_t *)os_malloc(buf_len);
if (send_data == NULL) {
CLI_LOGE("send buffer malloc failed\r\n");
return;
}
os_memset(send_data, 0, buf_len);
for (int i = 0; i < buf_len; i++) {
send_data[i] = i & 0xff;
}
BK_LOG_ON_ERR(bk_uart_write_bytes(uart_id, send_data, buf_len));
if (send_data) {
os_free(send_data);
}
send_data = NULL;
CLI_LOGI("uart write, uart_id=%d, data_len:%d\n", uart_id, buf_len);
} else if (os_strcmp(argv[2], "read") == 0) {
uint32_t buf_len = os_strtoul(argv[3], NULL, 10);
uint8_t *recv_data = (uint8_t *)os_malloc(buf_len);
if (recv_data == NULL) {
CLI_LOGE("recv buffer malloc failed\r\n");
return;
}
int time_out = os_strtoul(argv[4], NULL, 10);
if (time_out < 0) {
time_out = BEKEN_WAIT_FOREVER;
}
int data_len = bk_uart_read_bytes(uart_id, recv_data, buf_len, time_out);
if (data_len < 0) {
CLI_LOGE("uart read failed, ret:-0x%x\r\n", -data_len);
goto exit;
}
CLI_LOGI("uart read, uart_id=%d, time_out:%x data_len:%d\n", uart_id, time_out, data_len);
for (int i = 0; i < data_len; i++) {
CLI_LOGI("recv_buffer[%d]=0x%x\n", i, recv_data[i]);
}
exit:
if (recv_data) {
os_free(recv_data);
}
recv_data = NULL;
} else if (os_strcmp(argv[2], "write_string") == 0) {
char send_data[] = "beken uart write string test\r\n";
BK_LOG_ON_ERR(bk_uart_write_bytes(uart_id, send_data, os_strlen(send_data)));
CLI_LOGI("uart write string, uart_id=%d, data_len:%d\n", uart_id, os_strlen(send_data));
}
#if CONFIG_UART_STATIS
else if (os_strcmp(argv[2], "dump_statis") == 0) {
uart_statis_dump(uart_id);
CLI_LOGI("uart dump statis ok\r\n");
} else if (os_strcmp(argv[2], "reset_statis") == 0) {
uart_statis_id_init(uart_id);
CLI_LOGI("uart reset statis ok\r\n");
}
#endif
else {
cli_uart_help();
return;
}
}
static void cli_uart_config_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
uint32_t uart_id;
if (argc < 4) {
cli_uart_help();
return;
}
uart_id = os_strtoul(argv[1], NULL, 10);
if (os_strcmp(argv[2], "baud_rate") == 0) {
CLI_RET_ON_INVALID_ARGC(argc, 4);
uint32_t baud_rate = os_strtoul(argv[3], NULL, 10);
BK_LOG_ON_ERR(bk_uart_set_baud_rate(uart_id, baud_rate));
CLI_LOGI("uart(%d) config baud_rate:%d\n", uart_id, baud_rate);
} else if (os_strcmp(argv[2], "data_bits") == 0) {
CLI_RET_ON_INVALID_ARGC(argc, 4);
uint32_t data_bits = os_strtoul(argv[3], NULL, 10);
BK_LOG_ON_ERR(bk_uart_set_data_bits(uart_id, data_bits));
CLI_LOGI("uart(%d) config data_bits:%d\n", uart_id, data_bits);
} else if (os_strcmp(argv[2], "stop_bits") == 0) {
CLI_RET_ON_INVALID_ARGC(argc, 4);
uint32_t stop_bits = os_strtoul(argv[3], NULL, 10);
BK_LOG_ON_ERR(bk_uart_set_stop_bits(uart_id, stop_bits));
CLI_LOGI("uart(%d) config stop_bits:%d\n", uart_id, stop_bits);
} else if (os_strcmp(argv[2], "parity") == 0) {
CLI_RET_ON_INVALID_ARGC(argc, 4);
uint32_t parity = os_strtoul(argv[3], NULL, 10);
BK_LOG_ON_ERR(bk_uart_set_parity(uart_id, parity));
CLI_LOGI("uart(%d) config parity:%d\n", uart_id, parity);
} else if (os_strcmp(argv[2], "flow_ctrl") == 0) {
CLI_RET_ON_INVALID_ARGC(argc, 4);
uint32_t rx_threshold = os_strtoul(argv[3], NULL, 10);
BK_LOG_ON_ERR(bk_uart_set_hw_flow_ctrl(uart_id, rx_threshold));
CLI_LOGI("uart(%d) config flow_ctrl:%d\n", uart_id, rx_threshold);
} else if (os_strcmp(argv[2], "rx_thresh") == 0) {
CLI_RET_ON_INVALID_ARGC(argc, 4);
uint32_t rx_thresh = os_strtoul(argv[3], NULL, 10);
BK_LOG_ON_ERR(bk_uart_set_rx_full_threshold(uart_id, rx_thresh));
CLI_LOGI("uart(%d) config rx_thresh:%d\n", uart_id, rx_thresh);
} else if (os_strcmp(argv[2], "tx_thresh") == 0) {
CLI_RET_ON_INVALID_ARGC(argc, 4);
uint32_t tx_thresh = os_strtoul(argv[3], NULL, 10);
BK_LOG_ON_ERR(bk_uart_set_tx_empty_threshold(uart_id, tx_thresh));
CLI_LOGI("uart(%d) config tx_thresh:%d\n", uart_id, tx_thresh);
} else if (os_strcmp(argv[2], "rx_timeout") == 0) {
CLI_RET_ON_INVALID_ARGC(argc, 4);
uint32_t timeout_thresh = os_strtoul(argv[3], NULL, 10);
BK_LOG_ON_ERR(bk_uart_set_rx_timeout(uart_id, timeout_thresh));
CLI_LOGI("uart(%d) config rx_timeout:%d\n", uart_id, timeout_thresh);
} else {
cli_uart_help();
return;
}
}
static void cli_uart_rx_isr(uart_id_t id, void *param)
{
CLI_LOGI("uart_rx_isr(%d)\n", id);
}
static void cli_uart_tx_isr(uart_id_t id, void *param)
{
CLI_LOGI("uart_tx_isr(%d)\n", id);
}
static void cli_uart_int_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
uint32_t uart_id;
if (argc != 4) {
cli_uart_help();
return;
}
uart_id = os_strtoul(argv[1], NULL, 10);
if (os_strcmp(argv[2], "enable") == 0) {
if (os_strcmp(argv[3], "tx") == 0) {
BK_LOG_ON_ERR(bk_uart_enable_tx_interrupt(uart_id));
CLI_LOGI("uart id:%d enable tx interrupt\n", uart_id);
} else {
BK_LOG_ON_ERR(bk_uart_enable_rx_interrupt(uart_id));
CLI_LOGI("uart id:%d enable rx interrupt\n", uart_id);
}
} else if (os_strcmp(argv[2], "disable") == 0) {
if (os_strcmp(argv[3], "tx") == 0) {
BK_LOG_ON_ERR(bk_uart_disable_tx_interrupt(uart_id));
CLI_LOGI("uart id:%d disable tx interrupt\n", uart_id);
} else {
BK_LOG_ON_ERR(bk_uart_disable_rx_interrupt(uart_id));
CLI_LOGI("uart id:%d disable rx interrupt\n", uart_id);
}
} else if (os_strcmp(argv[2], "reg") == 0) {
if (os_strcmp(argv[3], "tx") == 0) {
BK_LOG_ON_ERR(bk_uart_register_tx_isr(uart_id, cli_uart_tx_isr, NULL));
CLI_LOGI("uart id:%d register tx interrupt isr\n", uart_id);
} else {
BK_LOG_ON_ERR(bk_uart_register_rx_isr(uart_id, cli_uart_rx_isr, NULL));
CLI_LOGI("uart id:%d register rx interrupt isr\n", uart_id);
}
} else {
cli_uart_help();
return;
}
}
#if CONFIG_IDLE_UART_OUT_TEST
static beken_thread_t idle_uart_out_test_handle = NULL;
static uint16_t idle_uart_out_test_id = 0;
static void cli_idle_uart_out_test_isr(uart_id_t id, void *param)
{
return;
}
static void cli_idle_uart_out_test(void *arg)
{
while (1) {
unsigned long random;
char tx_buffer[16];
random = bk_rand();
itoa(random, tx_buffer, 14);
tx_buffer[16] = '\0';
uart_write_string(idle_uart_out_test_id, tx_buffer);
}
rtos_delete_thread(&idle_uart_out_test_handle);
}
static void cli_uart_test_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
if (argc < 2) {
cli_uart_help();
return;
}
if (os_strcmp(argv[1], "idle_start") == 0) {
if (!idle_uart_out_test_handle) {
if (os_strcmp(argv[2], "uart1") == 0) {
#if !CONFIG_PRINT_PORT_UART1
idle_uart_out_test_id = UART_ID_0;
CLI_LOGI("idle_uart_out task start: uart_id = UART1\n" );
#else
CLI_LOGI("cli_uart_test_cmd UART1 for log output!!!\n");
return;
#endif
} else if (os_strcmp(argv[2], "uart2")== 0) {
#if !CONFIG_PRINT_PORT_UART2
idle_uart_out_test_id = UART_ID_1;
CLI_LOGI("idle_uart_out task start: uart_id = UART2\n" );
#else
CLI_LOGI("cli_uart_test_cmd UART2 for log output!!!\n");
return;
#endif
} else if (os_strcmp(argv[2], "uart3")== 0) {
#if !CONFIG_PRINT_PORT_UART3
idle_uart_out_test_id = UART_ID_2;
CLI_LOGI("idle_uart_out task start: uart_id = UART3\n" );
#else
CLI_LOGI("cli_uart_test_cmd UART3 for log output!!!\n");
return;
#endif
} else {
cli_uart_help();
return;
}
uart_config_t config = {0};
os_memset(&config, 0, sizeof(uart_config_t));
config.baud_rate = UART_BAUD_RATE;
config.data_bits = UART_DATA_8_BITS;
config.parity = UART_PARITY_NONE;
config.stop_bits = UART_STOP_BITS_1;
config.flow_ctrl = UART_FLOWCTRL_DISABLE;
config.src_clk = UART_SCLK_XTAL_26M;
BK_LOG_ON_ERR(bk_uart_init(idle_uart_out_test_id, &config));
BK_LOG_ON_ERR(bk_uart_deinit(idle_uart_out_test_id));
BK_LOG_ON_ERR(bk_uart_register_tx_isr(idle_uart_out_test_id, cli_idle_uart_out_test_isr, NULL));
BK_LOG_ON_ERR(bk_uart_enable_tx_interrupt(idle_uart_out_test_id));
BK_LOG_ON_ERR(bk_uart_init(idle_uart_out_test_id, &config));
BK_LOG_ON_ERR(bk_trng_driver_init());
BK_LOG_ON_ERR(bk_trng_start());
if(rtos_create_thread(&idle_uart_out_test_handle, 8, "idle_uart_out",
(beken_thread_function_t) cli_idle_uart_out_test, 2048, 0)) {
CLI_LOGI("cli_uart_test_cmd rtos_create_thread FAILED!\n");
return;
}
}else {
CLI_LOGI("PLEASE stop the task\n");
}
return;
} else if (os_strcmp(argv[1], "idle_stop") == 0) {
if (idle_uart_out_test_handle) {
if (os_strcmp(argv[2], "uart1") == 0) {
if(idle_uart_out_test_id != UART_ID_0) {
CLI_LOGI("PLEASE enter a correct ID\n");
return;
} else
idle_uart_out_test_id = UART_ID_0;
} else if (os_strcmp(argv[2], "uart2")== 0) {
if(idle_uart_out_test_id != UART_ID_1) {
CLI_LOGI("PLEASE enter a correct ID\n");
return;
} else
idle_uart_out_test_id = UART_ID_1;
} else if (os_strcmp(argv[2], "uart3")== 0) {
if(idle_uart_out_test_id != UART_ID_2) {
CLI_LOGI("PLEASE enter a correct ID\n");
return;
} else
idle_uart_out_test_id = UART_ID_2;
} else {
cli_uart_help();
return;
}
rtos_delete_thread(&idle_uart_out_test_handle);
idle_uart_out_test_handle = NULL;
BK_LOG_ON_ERR(bk_uart_disable_tx_interrupt(idle_uart_out_test_id));
BK_LOG_ON_ERR(bk_uart_register_tx_isr(idle_uart_out_test_id, NULL, NULL));
BK_LOG_ON_ERR(bk_uart_deinit(idle_uart_out_test_id));
BK_LOG_ON_ERR(bk_trng_stop());
CLI_LOGI("idle_uart_out task stop\n");
} else {
CLI_LOGI("PLEASE start task FIRST!!!\n");
}
return;
}
}
#endif //CONFIG_IDLE_UART_OUT_TEST
#define UART_CMD_CNT (sizeof(s_uart_commands) / sizeof(struct cli_command))
static const struct cli_command s_uart_commands[] = {
{"uart_driver", "{init|deinit}", cli_uart_driver_cmd},
{"uart", "uart {id} {init|deinit|write|read|write_string|dump_statis} [...]", cli_uart_cmd},
{"uart_config", "uart_config {id} {baud_rate|data_bits} [...]", cli_uart_config_cmd},
{"uart_int", "uart_int {id} {enable|disable|reg} {tx|rx}", cli_uart_int_cmd},
#if CONFIG_IDLE_UART_OUT_TEST
{"uart_test", "{idle_start|idle_stop} {uart1|uart2|uart3}", cli_uart_test_cmd},
#endif //CONFIG_IDLE_UART_OUT_TEST
};
int cli_uart_init(void)
{
BK_LOG_ON_ERR(bk_uart_driver_init());
return cli_register_commands(s_uart_commands, UART_CMD_CNT);
}
+102
View File
@@ -0,0 +1,102 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <os/os.h>
#include "cli.h"
#include <driver/wdt.h>
#include <bk_wdt.h>
static void cli_wdt_help(void)
{
CLI_LOGI("wdt_driver init\n");
CLI_LOGI("wdt_driver deinit\n");
CLI_LOGI("wdt start [timeout]\n");
CLI_LOGI("wdt stop\n");
CLI_LOGI("wdt feed\n");
}
static void cli_wdt_driver_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
if (argc < 2) {
cli_wdt_help();
return;
}
if (os_strcmp(argv[1], "init") == 0) {
BK_LOG_ON_ERR(bk_wdt_driver_init());
CLI_LOGI("wdt driver init\n");
} else if (os_strcmp(argv[1], "deinit") == 0) {
BK_LOG_ON_ERR(bk_wdt_driver_deinit());
CLI_LOGI("wdt driver deinit\n");
} else {
cli_wdt_help();
return;
}
}
static void cli_wdt_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
if (argc < 2) {
cli_wdt_help();
return;
}
if (os_strcmp(argv[1], "start") == 0) {
uint32_t timeout = os_strtoul(argv[2], NULL, 10);
BK_LOG_ON_ERR(bk_wdt_start(timeout));
CLI_LOGI("wdt start, timeout=%d\n", timeout);
} else if (os_strcmp(argv[1], "stop") == 0) {
BK_LOG_ON_ERR(bk_wdt_stop());
CLI_LOGI("wdt stop\n");
}else if (os_strcmp(argv[1], "feed") == 0) {
BK_LOG_ON_ERR(bk_wdt_feed());
CLI_LOGI("wdt feed\n");
}else if (os_strcmp(argv[1], "disable") == 0) {
extern void wdt_debug_disable(void);
wdt_debug_disable();
bk_wdt_stop();
bk_task_wdt_stop();
CLI_LOGI("wdt debug disabled\n");
}else if (os_strcmp(argv[1], "enable") == 0) {
extern void wdt_debug_enable(void);
extern void wdt_init(void);
wdt_debug_enable();
wdt_init();
CLI_LOGI("wdt debug enabled\n");
}else if (os_strcmp(argv[1], "while") == 0) {
GLOBAL_INT_DECLARATION();
GLOBAL_INT_DISABLE();
CLI_LOGI("wdt enter while1\n");
while(1);
GLOBAL_INT_RESTORE();
} else {
cli_wdt_help();
return;
}
}
#define WDT_CMD_CNT (sizeof(s_wdt_commands) / sizeof(struct cli_command))
static const struct cli_command s_wdt_commands[] = {
{"wdt_driver", "{init|deinit}", cli_wdt_driver_cmd},
{"wdt", "wdt {start|stop|feed} [...]", cli_wdt_cmd}
};
int cli_wdt_init(void)
{
BK_LOG_ON_ERR(bk_wdt_driver_init());
return cli_register_commands(s_wdt_commands, WDT_CMD_CNT);
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
int bk_cli_init(void);
#if CONFIG_SHELL_ASYNCLOG
#include <stdarg.h>
#include "components/shell_task.h"
#endif // #if CONFIG_SHELL_ASYNCLOG
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,214 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <common/bk_include.h>
#include <driver/uart.h>
#ifdef __cplusplus
extern "C" {
#endif
#define CLI_UART CONFIG_UART_PRINT_PORT
#define RX_WAIT BEKEN_WAIT_FOREVER
#define SEND_WAIT BEKEN_WAIT_FOREVER
#define RET_CHAR '\n'
#define END_CHAR '\r'
#define PROMPT "\r\n# "
#define EXIT_MSG "exit"
#define NUM_BUFFERS 1
#ifndef CONFIG_MAX_COMMANDS
#define MAX_COMMANDS 255
#else
#define MAX_COMMANDS CONFIG_MAX_COMMANDS
#endif
#ifdef CONFIG_KEYVALUE
#define INBUF_SIZE 1024
#else
#define INBUF_SIZE 128
#endif
#define OUTBUF_SIZE 2048
#define LOG_SERVICE_BUFLEN 100
#ifndef CFG_CLI_DEBUG
#define CFG_CLI_DEBUG 1
#endif
#if CFG_CLI_DEBUG
#define CLI_GETCHAR_TIMEOUT (120000)
#define CLI_COMMAND_IS_RUNNING (1)
#else
#define CLI_GETCHAR_TIMEOUT BEKEN_NEVER_TIMEOUT
#endif
/** Structure for registering CLI commands */
struct cli_command
{
/** The name of the CLI command */
const char *name;
/** The help text associated with the command */
const char *help;
/** The function that should be invoked for this command. */
void (*function) (char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
};
struct cli_st
{
int initialized;
const struct cli_command *commands[MAX_COMMANDS];
unsigned int num_commands;
#if ((!CONFIG_SHELL_ASYNCLOG) || CONFIG_ATE_TEST)
int echo_disabled;
unsigned int bp; /* buffer pointer */
char inbuf[INBUF_SIZE];
char outbuf[OUTBUF_SIZE];
#endif
} ;
#define cmd_printf(...) do{\
if (xWriteBufferLen > 0) {\
snprintf(pcWriteBuffer, xWriteBufferLen, __VA_ARGS__);\
xWriteBufferLen-= os_strlen(pcWriteBuffer);\
pcWriteBuffer+= os_strlen(pcWriteBuffer);\
}\
}while(0)
#define CLI_ARGS char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv
#define is_print(c) ((uint8_t)c >= 0x20 && (uint8_t)c <= 0x7f)
#if (CONFIG_SOC_BK7271)
void bk7271_dsp_cli_init(void);
#if CONFIG_BT
void bk7271_ble_cli_init(void);
#endif
#endif
#if (CONFIG_SOC_BK7256XX)
void usb_cli_init(void);
#endif
/** Register a CLI command
*
* This function registers a command with the command-line interface.
*
* \param[in] command The structure to register one CLI command
* \return 0 on success
* \return 1 on failure
*/
int cli_register_command(const struct cli_command *command);
/** Unregister a CLI command
*
* This function unregisters a command from the command-line interface.
*
* \param[in] command The structure to unregister one CLI command
* \return 0 on success
* \return 1 on failure
*/
int cli_unregister_command(const struct cli_command *command);
/** Stop the CLI thread and carry out the cleanup
*
* \return kNoErr on success
* \return error code otherwise.
*
*/
int cli_stop(void);
/** Register a batch of CLI commands
*
* Often, a module will want to register several commands.
*
* \param[in] commands Pointer to an array of commands.
* \param[in] num_commands Number of commands in the array.
* \return 0 on success
* \return 1 on failure
*/
int cli_register_commands(const struct cli_command *commands, int num_commands);
/** Unregister a batch of CLI commands
*
* \param[in] commands Pointer to an array of commands.
* \param[in] num_commands Number of commands in the array.
* \return 0 on success
* \return 1 on failure
*/
int cli_unregister_commands(const struct cli_command *commands,
int num_commands);
/* Get a CLI msg
*
* If an external input task wants to use the CLI, it can use
* cli_get_cmd_buffer() to get a command buffer that it can then
* submit to the CLI later using cli_submit_cmd_buffer().
*
* \param buff Pointer to a char * to place the buffer pointer in.
* \return 0 on success
* \return error code otherwise.
*/
int cli_getchar(char *inbuf);
int cli_getchars(char *inbuf, int len);
int cli_get_all_chars_len(void);
int cli_getchars_prefetch(char *inbuf, int len);
/* Send CLI output msg
*
* \param buff Pointer to a char * buffer.
* \return 0 on success
* \return error code otherwise.
*/
int cli_printf(const char *buff, ...);
// library CLI APIs
void ifconfig_Command(CLI_ARGS);
void arp_Command(CLI_ARGS);
void ping_Command(CLI_ARGS);
void dns_Command(CLI_ARGS);
void socket_show_Command(CLI_ARGS);
void memory_show_Command(CLI_ARGS);
void memory_dump_Command(CLI_ARGS);
void memory_set_Command(CLI_ARGS);
void memp_dump_Command(CLI_ARGS);
void cli_show_running_command(void);
int cli_init(void);
void ble_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
#ifdef MOC
void task_Command(CLI_ARGS);
#endif
#if CONFIG_SHELL_ASYNCLOG
int handle_shell_input(char *inbuf, int in_buf_size, char * outbuf, int out_buf_size);
#endif
#ifdef __cplusplus
}
#endif
+141
View File
@@ -0,0 +1,141 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 _shell_drv_h_
#define _shell_drv_h_
#ifdef __cplusplus
extern "C" {
#endif
#include <common/bk_typedef.h>
typedef enum
{
bFALSE = 0,
bTRUE = !bFALSE,
} bool_t;
typedef enum
{
SHELL_IO_CTRL_GET_STATUS = 0,
SHELL_IO_CTRL_RX_RESET,
SHELL_IO_CTRL_TX_RESET,
SHELL_IO_CTRL_FLUSH,
SHELL_IO_CTRL_SET_UART_PORT,
SHELL_IO_CTRL_GET_RX_STATUS,
} shell_ctrl_cmd_t;
enum
{
SHELL_DEV_UART = 0,
SHELL_DEV_MAILBOX,
};
struct _shell_dev_drv;
typedef struct
{
struct _shell_dev_drv *dev_drv;
u8 dev_type;
void * dev_ext;
} shell_dev_t;
typedef void (* tx_complete_t)(u8 *pbuf, u16 Tag);
typedef void (* rx_indicate_t)(void);
typedef struct _shell_dev_drv
{
bool_t (*init)(shell_dev_t * shell_dev);
bool_t (*open)(shell_dev_t * shell_dev, tx_complete_t tx_callback, rx_indicate_t rx_callback);
u16 (*write_async)(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen, u16 Tag);
u16 (*read)(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen);
u16 (*write_sync)(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen);
u16 (*write_echo)(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen);
bool_t (*io_ctrl)(shell_dev_t * shell_dev, u8 cmd, void * param);
bool_t (*close)(shell_dev_t * shell_dev);
} shell_dev_drv_t;
extern shell_dev_t shell_uart;
extern shell_dev_t shell_dev_mb;
extern shell_dev_t shell_uart3;
#ifdef CONFIG_DUAL_CORE
#include "mailbox_channel.h"
struct _shell_ipc_drv;
typedef struct
{
struct _shell_ipc_drv *dev_drv;
u8 dev_type;
void * dev_ext;
} shell_dev_ipc_t;
typedef int (* shell_ipc_rx_t)(u16 cmd, void *data_buf, u16 dataLen);
typedef struct _shell_ipc_drv
{
bool_t (*init)(shell_dev_ipc_t * dev_ipc);
bool_t (*open)(shell_dev_ipc_t * dev_ipc, shell_ipc_rx_t rx_callback);
u16 (*read)(shell_dev_ipc_t * dev_ipc, u8 * pBuf, u16 BufLen);
u16 (*write_sync)(shell_dev_ipc_t * dev_ipc, u8 * pBuf, u16 BufLen);
bool_t (*io_ctrl)(shell_dev_ipc_t * dev_ipc, u8 cmd, void * param);
bool_t (*close)(shell_dev_ipc_t * dev_ipc);
} shell_ipc_drv_t;
typedef union
{
struct
{
mb_chnl_hdr_t hdr;
u8 * buf;
u16 len;
u16 tag;
};
mb_chnl_cmd_t cmd_buf;
} log_cmd_t;
typedef union
{
struct
{
mb_chnl_hdr_t hdr;
u8 * buf;
u16 len;
};
mb_chnl_cmd_t cmd_buf;
} user_cmd_t;
enum
{
MB_CMD_LOG_OUT = 1,
MB_CMD_LOG_OUT_OK,
MB_CMD_USER_INPUT,
MB_CMD_ASSERT_OUT,
} ;
extern shell_dev_ipc_t shell_dev_ipc;
#endif /* CONFIG_DUAL_CORE */
#ifdef __cplusplus
}
#endif
#endif /* _shell_drv_h_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,536 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include "cli.h"
#include "shell_drv.h"
#define TX_QUEUE_LEN 8
#define RX_BUFF_SIZE 160
#define ECHO_BUFF_SIZE 64
typedef struct
{
u8 * packet;
u16 len;
u16 tag;
} dev_tx_packet_t;
typedef struct
{
u8 uart_id;
/* ======== TX channel ======= */
/* tx queue */
dev_tx_packet_t tx_list[TX_QUEUE_LEN];
u16 list_out_idx;
u16 list_in_idx;
/* currently tx packet info */
u8 *cur_packet;
u16 packet_len;
u16 packet_tag;
u16 packet_tx_len;
u8 tx_stopped;
u8 echo_buff[ECHO_BUFF_SIZE];
u8 echo_wr_idx;
u8 echo_rd_idx;
tx_complete_t tx_complete_callback;
/* ======== RX channel ======= */
/* rx buffer */
u8 rx_buff[RX_BUFF_SIZE];
u16 rx_buff_wr_idx;
u16 rx_buff_rd_idx;
u8 rx_over_flow;
rx_indicate_t rx_indicate_callback;
} shell_uart_ext_t;
static bool_t shell_uart_init(shell_dev_t * shell_dev);
static bool_t shell_uart_open(shell_dev_t * shell_dev, tx_complete_t tx_callback, rx_indicate_t rx_callback);
static u16 shell_uart_write_async(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen, u16 Tag);
static u16 shell_uart_read(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen);
static u16 shell_uart_write_sync(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen);
static u16 shell_uart_write_echo(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen);
static bool_t shell_uart_ctrl(shell_dev_t * shell_dev, u8 cmd, void *param);
static bool_t shell_uart_close(shell_dev_t * shell_dev);
static const shell_dev_drv_t shell_uart_drv =
{
.init = shell_uart_init,
.open = shell_uart_open,
.write_async = shell_uart_write_async,
.read = shell_uart_read,
.write_sync = shell_uart_write_sync,
.write_echo = shell_uart_write_echo,
.io_ctrl = shell_uart_ctrl,
.close = shell_uart_close
};
static shell_uart_ext_t uart1_ext =
{
.uart_id = CONFIG_UART_PRINT_PORT
};
shell_dev_t shell_uart =
{
.dev_drv = (struct _shell_dev_drv *)&shell_uart_drv,
.dev_type = SHELL_DEV_UART,
.dev_ext = &uart1_ext
};
#if 0
static shell_uart_ext_t uart3_ext =
{
.uart_id = UART_ID_2
};
shell_dev_t shell_uart3 =
{
.dev_drv = (struct _shell_dev_drv *)&shell_uart_drv,
.dev_type = SHELL_DEV_UART,
.dev_ext = &uart3_ext
};
#endif
/* =============================== internal functions =========================== */
static void shell_uart_rx_isr(int uartn, shell_uart_ext_t *uart_ext)
{
u16 free_buff_len, rx_cnt = 0;
u8 rx_data;
int ret = -1;
(void)uartn;
if(uart_ext->rx_buff_wr_idx >= uart_ext->rx_buff_rd_idx)
{
free_buff_len = RX_BUFF_SIZE - uart_ext->rx_buff_wr_idx + uart_ext->rx_buff_rd_idx;
}
else
{
free_buff_len = uart_ext->rx_buff_rd_idx - uart_ext->rx_buff_wr_idx;
}
while(bTRUE) /* read all data from rx-FIFO. */
{
ret = uart_read_byte_ex(uart_ext->uart_id, &rx_data);
if (ret == -1)
break;
rx_cnt++;
/* rx_buff_wr_idx == rx_buff_rd_idx means empty, so reserve one byte. */
if(rx_cnt < free_buff_len) /* reserved one byte space. */
{
uart_ext->rx_buff[uart_ext->rx_buff_wr_idx] = rx_data;
uart_ext->rx_buff_wr_idx = (uart_ext->rx_buff_wr_idx + 1) % RX_BUFF_SIZE;
}
else
{
/* discard rx-data, rx overflow. */
uart_ext->rx_over_flow = 1; // bTRUE; // rx overflow, disable rx interrupt to stop rx.
}
}
if(uart_ext->rx_indicate_callback != NULL)
{
uart_ext->rx_indicate_callback();
}
}
static void shell_uart_tx_isr(int uartn, shell_uart_ext_t *uart_ext)
{
int ret;
(void)uartn;
while(bTRUE) /* write data to tx-FIFO. */
{
ret = uart_write_ready(uart_ext->uart_id);
if(ret != 0)
break;
/* previous packet tx complete, check ECHO before new packet. */
if((uart_ext->cur_packet == NULL) || (uart_ext->packet_len == 0))
{
if(uart_ext->echo_rd_idx != uart_ext->echo_wr_idx) /* tx echo firstly. */
{
uart_write_byte(uart_ext->uart_id, uart_ext->echo_buff[uart_ext->echo_rd_idx]);
uart_ext->echo_rd_idx = (uart_ext->echo_rd_idx + 1) % ECHO_BUFF_SIZE;
continue; /* continue to ECHO next byte to tx-FIFO. */
}
else
{
if(uart_ext->list_out_idx != uart_ext->list_in_idx)
{
uart_ext->cur_packet = uart_ext->tx_list[uart_ext->list_out_idx].packet;
uart_ext->packet_len = uart_ext->tx_list[uart_ext->list_out_idx].len;
uart_ext->packet_tag = uart_ext->tx_list[uart_ext->list_out_idx].tag;
uart_ext->packet_tx_len = 0;
}
else
{
/* all packets tx complete. */
/* disable tx interrupt ? */ // disable TX firstly, then set tx_stopped to 1.
bk_uart_disable_tx_interrupt(uart_ext->uart_id);
uart_ext->tx_stopped = 1; /* bTRUE;*/ /* all data tranferred, tx stopped.*/
break;
}
}
}
if(uart_ext->packet_tx_len < uart_ext->packet_len)
{
uart_write_byte(uart_ext->uart_id, uart_ext->cur_packet[uart_ext->packet_tx_len]);
uart_ext->packet_tx_len++;
continue; /* continue to TX next byte to tx-FIFO. */
}
else
{
/* sent the whole packet, notify app. */
if(uart_ext->tx_complete_callback != NULL)
{
uart_ext->tx_complete_callback(uart_ext->cur_packet, uart_ext->packet_tag);
}
uart_ext->cur_packet = NULL;
uart_ext->packet_len = 0;
uart_ext->packet_tx_len = 0;
/* to next packet. */
uart_ext->list_out_idx = (uart_ext->list_out_idx + 1) % TX_QUEUE_LEN;
continue; /* continue to TX next packet. */
}
}
}
static void shell_uart_flush(shell_uart_ext_t *uart_ext)
{
int ret;
while(uart_ext->tx_stopped == 0) /* log tx pending. */
{
ret = uart_write_ready(uart_ext->uart_id);
if(ret == BK_OK)
{
shell_uart_tx_isr(uart_ext->uart_id, uart_ext);
}
}
}
static void shell_uart_tx_trigger(shell_uart_ext_t *uart_ext)
{
if(uart_ext->tx_stopped == 0)
return;
uart_ext->tx_stopped = 0; // set tx_stopped to 0 firstly, then enable TX.
bk_uart_enable_tx_interrupt(uart_ext->uart_id);
}
/* =============================== shell uart driver APIs =========================== */
static bool_t shell_uart_init(shell_dev_t * shell_dev)
{
u8 uart_id;
shell_uart_ext_t *uart_ext;
if(shell_dev == NULL)
return bFALSE;
uart_ext = (shell_uart_ext_t *)shell_dev->dev_ext;
uart_id = uart_ext->uart_id;
memset(uart_ext, 0, sizeof(shell_uart_ext_t));
uart_ext->rx_over_flow = 0;
uart_ext->tx_stopped = 1;
uart_ext->uart_id = uart_id;
return bTRUE;
}
static bool_t shell_uart_open(shell_dev_t * shell_dev, tx_complete_t tx_callback, rx_indicate_t rx_callback)
{
shell_uart_ext_t *uart_ext;
if(shell_dev == NULL)
return bFALSE;
uart_ext = (shell_uart_ext_t *)shell_dev->dev_ext;
uart_ext->tx_complete_callback = tx_callback;
uart_ext->rx_indicate_callback = rx_callback;
bk_uart_disable_sw_fifo(uart_ext->uart_id);
// call uart driver to register isr callback;
bk_uart_register_rx_isr(uart_ext->uart_id, (uart_isr_t)shell_uart_rx_isr, uart_ext);
bk_uart_register_tx_isr(uart_ext->uart_id, (uart_isr_t)shell_uart_tx_isr, uart_ext);
bk_uart_enable_rx_interrupt(uart_ext->uart_id);
return bTRUE;
}
static u16 shell_uart_write_async(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen, u16 Tag)
{
u16 free_items;
shell_uart_ext_t *uart_ext;
if(shell_dev == NULL)
return 0;
uart_ext = (shell_uart_ext_t *)shell_dev->dev_ext;
if((pBuf == NULL) /*|| (BufLen == 0)*/)
return 0;
/* enqueue pBuf even if BufLen is 0, upper layer need tx-complete-callback to free this pBuf. */
if(uart_ext->list_out_idx > uart_ext->list_in_idx)
free_items = uart_ext->list_out_idx - uart_ext->list_in_idx;
else
free_items = TX_QUEUE_LEN - uart_ext->list_in_idx + uart_ext->list_out_idx;
/* list_out_idx == list_in_idx means empty, so reserved one item. */
if(free_items > 1)
{
uart_ext->tx_list[uart_ext->list_in_idx].packet = pBuf;
uart_ext->tx_list[uart_ext->list_in_idx].len = BufLen;
uart_ext->tx_list[uart_ext->list_in_idx].tag = Tag;
uart_ext->list_in_idx = (uart_ext->list_in_idx + 1) % TX_QUEUE_LEN;
shell_uart_tx_trigger(uart_ext);
return 1;
}
else
{
return 0;
}
}
static u16 shell_uart_read(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen)
{
u16 read_cnt = 0;
shell_uart_ext_t *uart_ext;
if(shell_dev == NULL)
return 0;
uart_ext = (shell_uart_ext_t *)shell_dev->dev_ext;
if((pBuf == NULL) || (BufLen == 0))
return 0;
while(uart_ext->rx_buff_rd_idx != uart_ext->rx_buff_wr_idx)
{
pBuf[read_cnt] = uart_ext->rx_buff[uart_ext->rx_buff_rd_idx];
uart_ext->rx_buff_rd_idx = (uart_ext->rx_buff_rd_idx + 1) % RX_BUFF_SIZE;
read_cnt++;
if(read_cnt >= BufLen)
break;
}
return read_cnt;
}
/* call this after interrupt is DISABLED. */
static u16 shell_uart_write_sync(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen)
{
shell_uart_ext_t *uart_ext;
if(shell_dev == NULL)
return 0;
uart_ext = (shell_uart_ext_t *)shell_dev->dev_ext;
if((pBuf == NULL) || (BufLen == 0))
return 0;
u16 wr_cnt = 0;
while(bTRUE) /* write data to tx-FIFO. */
{
uart_write_byte(uart_ext->uart_id, *pBuf); // it is macro define, do NOT use *pBuf++;
pBuf++; wr_cnt++;
if(wr_cnt >= BufLen)
break;
}
return BufLen;
}
static u16 shell_uart_write_echo(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen)
{
u16 free_buff_len, wr_cnt = 0;
shell_uart_ext_t *uart_ext;
if(shell_dev == NULL)
return 0;
uart_ext = (shell_uart_ext_t *)shell_dev->dev_ext;
if((pBuf == NULL) || (BufLen == 0))
return 0;
if(uart_ext->echo_wr_idx >= uart_ext->echo_rd_idx)
{
free_buff_len = ECHO_BUFF_SIZE - uart_ext->echo_wr_idx + uart_ext->echo_rd_idx;
}
else
{
free_buff_len = uart_ext->echo_rd_idx - uart_ext->echo_wr_idx;
}
/* echo_wr_idx == echo_rd_idx means empty, so reserved one byte. */
while(free_buff_len > 1)
{
uart_ext->echo_buff[uart_ext->echo_wr_idx] = pBuf[wr_cnt];
uart_ext->echo_wr_idx = (uart_ext->echo_wr_idx + 1) % ECHO_BUFF_SIZE;
free_buff_len--;
wr_cnt++;
if(wr_cnt >= BufLen)
break;
}
if(wr_cnt > 0)
shell_uart_tx_trigger(uart_ext);
return wr_cnt;
}
static bool_t shell_uart_ctrl(shell_dev_t * shell_dev, u8 cmd, void *param)
{
shell_uart_ext_t *uart_ext;
if(shell_dev == NULL)
return bFALSE;
uart_ext = (shell_uart_ext_t *)shell_dev->dev_ext;
switch(cmd)
{
case SHELL_IO_CTRL_GET_STATUS:
if(param == NULL)
return bFALSE;
u16 free_items;
if(uart_ext->list_out_idx > uart_ext->list_in_idx)
free_items = uart_ext->list_out_idx - uart_ext->list_in_idx;
else
free_items = TX_QUEUE_LEN - uart_ext->list_in_idx + uart_ext->list_out_idx;
if(free_items > 1)
*((u16 *)param) = free_items - 1;
else
*((u16 *)param) = 0;
break;
case SHELL_IO_CTRL_RX_RESET:
uart_ext->rx_buff_rd_idx = 0;
uart_ext->rx_buff_wr_idx = 0;
break;
case SHELL_IO_CTRL_TX_RESET:
uart_ext->list_out_idx = 0;
uart_ext->list_in_idx = 0;
uart_ext->cur_packet = NULL;
uart_ext->packet_len = 0;
uart_ext->packet_tx_len = 0;
break;
case SHELL_IO_CTRL_FLUSH:
shell_uart_flush(uart_ext);
break;
case SHELL_IO_CTRL_SET_UART_PORT:
if(param == NULL) {
return bFALSE;
}
u8 uart_port = *(u8 *)param;
uart_ext->uart_id = uart_port;
break;
case SHELL_IO_CTRL_GET_RX_STATUS:
if(param == NULL)
return bFALSE;
*((u16 *)param) = uart_ext->rx_over_flow;
uart_ext->rx_over_flow = 0; // clear it after read by user.
break;
default:
return bFALSE;
break;
}
return bTRUE;
}
static bool_t shell_uart_close(shell_dev_t * shell_dev)
{
shell_uart_ext_t *uart_ext;
if(shell_dev == NULL)
return bFALSE;
uart_ext = (shell_uart_ext_t *)shell_dev->dev_ext;
// call uart driver to register isr callback;
bk_uart_register_rx_isr(uart_ext->uart_id, NULL, NULL);
bk_uart_register_tx_isr(uart_ext->uart_id, NULL, NULL);
uart_ext->tx_complete_callback = NULL;
uart_ext->rx_indicate_callback = NULL;
return bTRUE;
}
+20
View File
@@ -0,0 +1,20 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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")
import("${beken_sdk_dir}/sdkconfig.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
module_name = get_path_info(rebase_path("."), "name")
static_library(module_name) {
sources = [ "event.c" ]
}
+38
View File
@@ -0,0 +1,38 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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")
import("${beken_sdk_dir}/sdkconfig.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
module_name = get_path_info(rebase_path("."), "name")
static_library(module_name) {
sources = [
"components_init.c",
"legacy_init.c",
]
public_configs = [
"${beken_sdk_dir}/components/bk_cli:public",
"${beken_sdk_dir}/components/easy_flash:public",
"${beken_sdk_dir}/middleware/driver:public",
"${beken_sdk_dir}/middleware/boards:public",
"${beken_sdk_dir}/middleware/soc:public",
"${beken_sdk_dir}/middleware/arch:public",
]
}
config("public") {
include_dirs = [
".",
"include",
]
}
+20
View File
@@ -0,0 +1,20 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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")
import("${beken_sdk_dir}/sdkconfig.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
module_name = get_path_info(rebase_path("."), "name")
static_library(module_name) {
sources = [ "log.c" ]
}
+33
View File
@@ -0,0 +1,33 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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")
import("${beken_sdk_dir}/sdkconfig.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
module_name = get_path_info(rebase_path("."), "name")
static_library(module_name) {
sources = [ "bk_netif.c" ]
public_configs = [
":public",
"${beken_sdk_dir}/components/bk_os:public",
"${beken_sdk_dir}/components/bk_wifi:public",
]
}
config("public") {
include_dirs = [
"include",
"//third_party/lwip/src/include",
"${third_party_adatpter_path}/lwip_intf_v2_1/lwip-2.1.2/port",
]
}
+41
View File
@@ -0,0 +1,41 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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")
import("${beken_sdk_dir}/sdkconfig.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
module_name = get_path_info(rebase_path("."), "name")
static_library(module_name) {
sources = [
"liteos_m_mst/mem_arch.c",
"liteos_m_mst/os_clock.c",
"liteos_m_mst/port.c",
"liteos_m_mst/rtos_pub.c",
"liteos_m_mst/str_arch.c",
"platform_stub.c",
"rtos_ext.c",
]
public_configs = [
":public",
"${beken_sdk_dir}/middleware/arch:public",
"${beken_sdk_dir}/middleware/driver:public",
]
}
config("public") {
include_dirs = [
".",
"include",
"liteos_m_mst",
]
}
@@ -35,6 +35,7 @@
#include "los_arch_timer.h"
#include "los_sched.h"
#include "platform.h"
#define ISR_STACK_SIZE 1024
#define BYTE_ALIGNMENT_MASK ( 0x000f )
@@ -0,0 +1,153 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <common/bk_include.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <os/str.h>
#include <os/mem.h>
char *os_strchr(const char *s, int c)
{
return strchr(s, c);
}
UINT32 os_strlen(const char *str)
{
return strlen(str);
}
INT32 os_strcmp(const char *s1, const char *s2)
{
return strcmp(s1, s2);
}
UINT32 os_strtoul(const char *nptr, char **endptr, int base)
{
return strtoul(nptr, endptr, base);
}
char *os_strcpy(char *out, const char *in)
{
return strcpy(out, in);
}
char *os_strncpy(char *out, const char *in, const UINT32 n)
{
return strncpy(out, in, (unsigned int)n);
}
size_t os_strlcpy(char *dest, const char *src, size_t siz)
{
const char *s = src;
size_t left = siz;
if (left)
{
/* Copy string up to the maximum size of the dest buffer */
while (--left != 0)
{
if ((*dest++ = *s++) == '\0')
break;
}
}
if (left == 0)
{
/* Not enough room for the string; force NUL-termination */
if (siz != 0)
*dest = '\0';
while (*s++)
; /* determine total src string length */
}
return s - src - 1;
}
INT32 os_strncmp(const char *s1, const char *s2, const UINT32 n)
{
return strncmp(s1, s2, (unsigned int)n);
}
INT32 os_snprintf(char *buf, UINT32 size, const char *fmt, ...)
{
va_list args;
INT32 rc;
va_start(args, fmt);
rc = vsnprintf(buf, size, fmt, args);
va_end(args);
/* if want to print more than the limitation */
if (rc > size)
rc = (INT32)size - rc;
return rc;
}
INT32 os_vsnprintf(char *buf, UINT32 size, const char *fmt, va_list ap)
{
return vsnprintf(buf, size, fmt, ap);
}
char *os_strdup(const char *s)
{
char *res;
size_t len;
if (s == NULL)
return NULL;
len = os_strlen(s);
res = os_malloc(len + 1);
if (res)
os_memcpy(res, s, len + 1);
return res;
}
int os_strcasecmp(const char *s1, const char *s2)
{
/*
* Ignoring case is not required for main functionality, so just use
* the case sensitive version of the function.
*/
return os_strcmp(s1, s2);
}
int os_strncasecmp(const char *s1, const char *s2, size_t n)
{
/*
* Ignoring case is not required for main functionality, so just use
* the case sensitive version of the function.
*/
return os_strncmp(s1, s2, n);
}
char *os_strrchr(const char *s, int c)
{
return strrchr(s, c);
}
char *os_strstr(const char *haystack, const char *needle)
{
return strstr(haystack, needle);
}
// EOF
@@ -17,7 +17,7 @@
#include <stdio.h>
#include <sys/stat.h>
#include <sys/times.h>
#include <sys/unistd.h>
//#include <sys/unistd.h>
#include <os/mem.h>
@@ -25,7 +25,6 @@
#include <os/os.h>
#include "common/bk_assert.h"
/************** wrap C library functions **************/
void *__wrap_malloc(size_t size)
{
+26
View File
@@ -0,0 +1,26 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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")
import("${beken_sdk_dir}/sdkconfig.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
module_name = get_path_info(rebase_path("."), "name")
kernel_module(module_name) {
}
config("public") {
include_dirs = [
".",
"include",
]
}
@@ -0,0 +1,31 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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")
import("${beken_sdk_dir}/sdkconfig.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
module_name = get_path_info(rebase_path("."), "name")
static_library(module_name) {
sources = [
"liteos_m/rtos_init.c",
"system_main.c",
]
include_dirs = [ "liteos_m" ]
public_configs = [
"${beken_sdk_dir}/components/bk_init:public",
"${beken_sdk_dir}/components/bk_os:public",
"${beken_sdk_dir}/middleware/driver:public",
"${beken_sdk_dir}/middleware/arch:public",
"${beken_sdk_dir}/middleware/soc:public",
]
}
@@ -0,0 +1,43 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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")
import("${beken_sdk_dir}/sdkconfig.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
module_name = get_path_info(rebase_path("."), "name")
static_library(module_name) {
sources = [
"mac.c",
"os/liteos_m/tick.c",
"printf.c",
"printf_base.c",
"reboot.c",
"target_util.c",
"tick_base.c",
]
public_configs = [
":public",
"${beken_sdk_dir}/components/bk_os:public",
"${beken_sdk_dir}/components/bk_cli:public",
"${beken_sdk_dir}/components/bk_wifi:public",
"${beken_sdk_dir}/middleware/driver:public",
"${beken_sdk_dir}/middleware/soc:public",
]
}
config("public") {
include_dirs = [
"os/liteos_m",
"soc/bk7235",
]
}
@@ -1,17 +0,0 @@
// Copyright (C) 2022 Beken Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#define TICK_TIMER_ID BK_TIMER_ID1
@@ -1 +0,0 @@
armino_component_register()
@@ -1,66 +0,0 @@
menu "USB configuration"
config USB
bool "Enable USB"
default y
menu "USB"
depends on USB
#TODO HOST/DEVICE mode mutual exclusive
choice USB_MODE
prompt "Enable USB HOST mode"
default USB_HOST
config USB_HOST
bool "USB Host Mode"
config USB_DEVICE
bool "USB Device Mode"
endchoice
choice USB_PORT
prompt "Select USB Port"
default USB2_PORT
config USB1_PORT
bool "USB1 port"
config USB2_PORT
bool "USB2 port"
endchoice
config TASK_USB_PRIO
int "Priority of USB task"
range 1 10
default 5
config USB_MSD
bool "Enable USB MSD"
default y
config USB_HID
bool "Enable USB HID"
default n
config USB_CCD
bool "Enable USB CCD"
default n
config USB_UVC
bool "Enable USB UVC"
default n
config USB_CHARGE
bool "Enable USB Charge"
default n
menu "DSP"
config DSP
bool "Enable DSP"
default n
#TODO delete it
config DSP_SRC_ADD
hex "DSP srouce address"
default 0x130000
endmenu
endmenu
endmenu
+24
View File
@@ -0,0 +1,24 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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")
import("${beken_sdk_dir}/sdkconfig.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
config("public") {
include_dirs = [
"include",
"include/bk_private",
"include/bk_private/legacy",
]
}
@@ -0,0 +1,40 @@
* text=auto
*.S text
*.asm text
*.c text
*.cc text
*.cpp text
*.cxx text
*.h text
*.htm text
*.html text
*.in text
*.ld text
*.m4 text
*.mak text
*.mk text
*.py text
*.rb text
*.s text
*.sct text
*.sh text
*.txt text
*.xml text
Makefile text
AUTHORS text
COPYING text
*.LZO -text
*.Opt -text
*.Uv2 -text
*.ewp -text
*.eww -text
*.vcproj -text
*.bat -text
*.dos -text
*.icf -text
*.inf -text
*.ini -text
*.sct -text
*.xsd -text
@@ -0,0 +1,42 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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")
import("${beken_sdk_dir}/sdkconfig.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
module_name = get_path_info(rebase_path("."), "name")
static_library(module_name) {
sources = [
"bk_ef.c",
"port/ef_port.c",
"src/easyflash.c",
"src/ef_env.c",
"src/ef_env_wl.c",
"src/ef_iap.c",
"src/ef_log.c",
"src/ef_utils.c",
]
public_configs = [
":public",
"${beken_sdk_dir}/components/base64:public",
"${beken_sdk_dir}/middleware/driver:public",
]
}
config("public") {
include_dirs = [
".",
"inc",
"port",
]
}
@@ -0,0 +1,25 @@
set(incs
.
inc
port
)
set(srcs)
if (CONFIG_EASY_FLASH)
list(APPEND srcs
bk_ef.c
src/easyflash.c
src/ef_env.c
src/ef_env_wl.c
src/ef_iap.c
src/ef_log.c
src/ef_utils.c
port/ef_port.c
)
endif()
armino_component_register(SRCS "${srcs}"
INCLUDE_DIRS "${incs}"
REQUIRES base64
PRIV_REQUIRES bk_common)
@@ -0,0 +1,3 @@
config EASY_FLASH
bool "Enable Easy Flash"
default n
@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2014-2018 Armink (armink.ztl@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+111
View File
@@ -0,0 +1,111 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <common/bk_include.h>
#include "bk_ef.h"
#include "base_64.h"
#include <os/mem.h>
#include <os/str.h>
#if CONFIG_EASY_FLASH
char *bk_get_env(const char *key)
{
return ef_get_env(key);
}
EfErrCode bk_set_env(const char *key, const char *value)
{
return ef_set_env(key, value);
}
EfErrCode bk_save_env(void)
{
return ef_save_env();
}
EfErrCode bk_set_buf_env(const char *key, const char *buf, int len)
{
EfErrCode result;
unsigned char ret;
unsigned char *ef_value;
uint32_t buf_len;
int out_len;
if ((0 == len) || (NULL == key)
|| (NULL == buf))
return EF_ENV_INIT_FAILED;
buf_len = base64_calc_encode_length(len) + 4;
ef_value = os_zalloc(buf_len);
if (NULL == ef_value)
return EF_ENV_INIT_FAILED;
ret = base64_encode((unsigned char *)buf, len, &out_len, ef_value);
if (0 == ret) {
os_free(ef_value);
ef_value = NULL;
return EF_ENV_INIT_FAILED;
}
result = ef_set_env(key, (char *)ef_value);
os_free(ef_value);
return result;
}
EfErrCode bk_get_buf_env(const char *key, const char *buf, int len)
{
unsigned char *out_ptr;
unsigned char ret;
char *ef_value;
int out_buf_len, count;
int out_len, value_len;
ef_value = ef_get_env(key);
if (NULL == ef_value)
return EF_ENV_NAME_ERR;
value_len = os_strlen(ef_value);
if (0 == value_len)
return EF_ENV_INIT_FAILED;
out_buf_len = base64_calc_decode_length((unsigned char *)ef_value, value_len);
out_ptr = (unsigned char *)os_zalloc(out_buf_len + 4);
if (NULL == out_ptr)
return EF_ENV_INIT_FAILED;
ret = base64_decode((unsigned char *)ef_value, value_len, &out_len, out_ptr);
if (0 == ret) {
os_free(out_ptr);
out_ptr = NULL;
return EF_ENV_INIT_FAILED;
}
if (out_len) {
count = min(len, out_len);
BK_ASSERT(len == out_len);
os_memcpy((void *)buf, out_ptr, count);
}
os_free(out_ptr);
return EF_NO_ERR;
}
#endif // CONFIG_EASY_FLASH
// eof
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 _BK_EASY_FLASH_H_
#define _BK_EASY_FLASH_H_
#include "easyflash.h"
#if CONFIG_EASY_FLASH
EfErrCode bk_save_env(void);
char *bk_get_env(const char *key);
EfErrCode bk_set_env(const char *key, const char *value);
EfErrCode bk_set_buf_env(const char *key, const char *buf, int len);
EfErrCode bk_get_buf_env(const char *key, const char *buf, int len);
#endif // CONFIG_EASY_FLASH
#endif // _BK_EASY_FLASH_H_
// eof
@@ -0,0 +1,147 @@
/*
* Copyright (c) 2014-2018, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: It is an head file for this library. You can see all be called functions.
* Created on: 2014-09-10
*/
#ifndef _EASYFLASH_H_
#define _EASYFLASH_H_
#include <ef_cfg.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(EF_USING_ENV) && (!defined(ENV_USER_SETTING_SIZE) || !defined(ENV_AREA_SIZE))
#error "Please configure user setting ENV size or ENV area size (in ef_cfg.h)"
#endif
#if defined(EF_USING_LOG) && !defined(LOG_AREA_SIZE)
#error "Please configure log area size (in ef_cfg.h)"
#endif
#if !defined(EF_START_ADDR)
#error "Please configure backup area start address (in ef_cfg.h)"
#endif
#if !defined(EF_ERASE_MIN_SIZE)
#error "Please configure minimum size of flash erasure (in ef_cfg.h)"
#endif
/* EasyFlash debug print function. Must be implement by user. */
#define EF_DEBUG(...) ef_log_debug(__FILE__, __LINE__, __VA_ARGS__)
/* EasyFlash routine print function. Must be implement by user. */
#define EF_INFO(...) ef_log_info(__VA_ARGS__)
/* EasyFlash assert for developer. */
#define EF_ASSERT(EXPR) \
if (!(EXPR)) \
{ \
EF_DEBUG("(%s) has assert failed at %s.\n", #EXPR, __FUNCTION__); \
while (1); \
}
/* EasyFlash software version number */
#define EF_SW_VERSION "3.0.4"
typedef struct _ef_env {
char *key;
char *value;
} ef_env, *ef_env_t;
/* EasyFlash error code */
typedef enum {
EF_NO_ERR,
EF_ERASE_ERR,
EF_WRITE_ERR,
EF_ENV_NAME_ERR,
EF_ENV_NAME_EXIST,
EF_ENV_FULL,
EF_ENV_INIT_FAILED,
} EfErrCode;
/* the flash sector current status */
typedef enum {
EF_SECTOR_EMPTY,
EF_SECTOR_USING,
EF_SECTOR_FULL,
} EfSecrorStatus;
/* easyflash.c */
EfErrCode easyflash_init(void);
#ifdef EF_USING_ENV
/* ef_env.c ef_env_wl.c */
EfErrCode ef_load_env(void);
void ef_print_env(void);
char *ef_get_env(const char *key);
EfErrCode ef_set_env(const char *key, const char *value);
EfErrCode ef_save_env(void);
EfErrCode ef_env_set_default(void);
size_t ef_get_env_write_bytes(void);
EfErrCode ef_set_and_save_env(const char *key, const char *value);
#endif
#ifdef EF_USING_IAP
/* ef_iap.c */
EfErrCode ef_erase_bak_app(size_t app_size);
EfErrCode ef_erase_user_app(uint32_t user_app_addr, size_t user_app_size);
EfErrCode ef_erase_spec_user_app(uint32_t user_app_addr, size_t app_size,
EfErrCode(*app_erase)(uint32_t addr, size_t size));
EfErrCode ef_erase_bl(uint32_t bl_addr, size_t bl_size);
EfErrCode ef_write_data_to_bak(uint8_t *data, size_t size, size_t *cur_size,
size_t total_size);
EfErrCode ef_copy_app_from_bak(uint32_t user_app_addr, size_t app_size);
EfErrCode ef_copy_spec_app_from_bak(uint32_t user_app_addr, size_t app_size,
EfErrCode(*app_write)(uint32_t addr, const uint32_t *buf, size_t size));
EfErrCode ef_copy_bl_from_bak(uint32_t bl_addr, size_t bl_size);
uint32_t ef_get_bak_app_start_addr(void);
#endif
#ifdef EF_USING_LOG
/* ef_log.c */
EfErrCode ef_log_read(size_t index, uint32_t *log, size_t size);
EfErrCode ef_log_write(const uint32_t *log, size_t size);
EfErrCode ef_log_clean(void);
size_t ef_log_get_used_size(void);
#endif
/* ef_utils.c */
uint32_t ef_calc_crc32(uint32_t crc, const void *buf, size_t size);
/* ef_port.c */
EfErrCode ef_port_read(uint32_t addr, uint32_t *buf, size_t size);
EfErrCode ef_port_erase(uint32_t addr, size_t size);
EfErrCode ef_port_write(uint32_t addr, const uint32_t *buf, size_t size);
void ef_port_env_lock(void);
void ef_port_env_unlock(void);
void ef_log_debug(const char *file, const long line, const char *format, ...);
void ef_log_info(const char *format, ...);
void ef_print(const char *format, ...);
#ifdef __cplusplus
}
#endif
#endif /* EASYFLASH_H_ */
@@ -0,0 +1,105 @@
/*
* Copyright (c) 2015, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: It is the configure head file for this library.
* Created on: 2015-07-14
*/
#ifndef _EF_CFG_H_
#define _EF_CFG_H_
/* using ENV function */
#define EF_USING_ENV
/* using wear leveling mode for ENV */
/* #define EF_ENV_USING_WL_MODE */
/* using power fail safeguard mode for ENV */
#define EF_ENV_USING_PFS_MODE
/* using IAP function */
//#define EF_USING_IAP
/* using save log function */
//#define EF_USING_LOG
/* the minimum size of flash erasure */
#define EF_ERASE_MIN_SIZE 4096
/**
*
* This all Backup Area Flash storage index. All used flash area configure is under here.
* |----------------------------| Storage Size
* | Environment variables area | ENV area size @see ENV_AREA_SIZE
* | 1.system section | ENV_SYSTEM_SIZE
* | 2:data section | ENV_AREA_SIZE - ENV_SYSTEM_SIZE
* |----------------------------|
* | Saved log area | Log area size @see LOG_AREA_SIZE
* |----------------------------|
* |(IAP)Downloaded application | IAP already downloaded application, unfixed size
* |----------------------------|
*
* @note all area size must be aligned with EF_ERASE_MIN_SIZE
* @note EasyFlash will use ram to buffered the ENV. At some time flash's EF_ERASE_MIN_SIZE is so big,
* and you want use ENV size is less than it. So you must defined ENV_USER_SETTING_SIZE for ENV.
* @note ENV area size has some limitations in different modes.
* 1.Normal mode: no more limitations
* 2.Wear leveling mode: system section will used an flash section and the data section will used at least 2 flash sections
* 3.Power fail safeguard mode: ENV area will has an backup. It is twice as normal mode.
* 4.wear leveling and power fail safeguard mode: The required capacity will be 2 times the total capacity in wear leveling mode.
* For example:
* The EF_ERASE_MIN_SIZE is 128K and the ENV_USER_SETTING_SIZE: 2K. The ENV_AREA_SIZE in different mode you can define
* 1.Normal mode: 1*EF_ERASE_MIN_SIZE
* 2.Wear leveling mode: 3*EF_ERASE_MIN_SIZE (It has 2 data section to store ENV. So ENV can erase at least 200,000 times)
* 3.Power fail safeguard mode: 2*EF_ERASE_MIN_SIZE
* 4.Wear leveling and power fail safeguard mode: 6*EF_ERASE_MIN_SIZE
* @note the log area size must be more than twice of EF_ERASE_MIN_SIZE
*/
/* backup area start address */ /* start address of param partition */
#define EF_START_ADDR 0x3FA000 //(0x400000 - 12*2*1024) //(0x1FC000)
/* the user setting size of ENV, must be word alignment */
#define ENV_USER_SETTING_SIZE (12 * 1024 - 20)//(8 * 1024 - 20)
#ifndef EF_ENV_USING_PFS_MODE
#ifndef EF_ENV_USING_WL_MODE
/* ENV area total bytes size in normal mode. */
#define ENV_AREA_SIZE (1 * EF_ERASE_MIN_SIZE) /* 4K */
#else
/* ENV area total bytes size in wear leveling mode. */
#define ENV_AREA_SIZE (4 * EF_ERASE_MIN_SIZE) /* 16K */
#endif
#else
#ifndef EF_ENV_USING_WL_MODE
/* ENV area total bytes size in power fail safeguard mode. */
#define ENV_AREA_SIZE ((12*2/4) * EF_ERASE_MIN_SIZE) /* 16K */
#else
/* ENV area total bytes size in wear leveling and power fail safeguard mode. */
#define ENV_AREA_SIZE (6 * EF_ERASE_MIN_SIZE) /* 24K */
#endif
#endif
/* saved log area size */
#define LOG_AREA_SIZE (254 * EF_ERASE_MIN_SIZE) /* 1016K */
/* print debug information of flash */
//#define PRINT_DEBUG
#endif /* EF_CFG_H_ */
@@ -0,0 +1,316 @@
/*
* Copyright (c) 2015, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: Portable interface for stm32f4xx platform.
* Created on: 2015-01-16
*/
#include <common/bk_include.h>
#include <easyflash.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#if CONFIG_FLASH_ORIGIN_API
#include "bk_flash.h"
#include "flash.h"
#else
#include "driver/flash.h"
#endif
#include <os/os.h>
#include "bk_uart.h"
#include "bk_drv_model.h"
/* default ENV set for user */
static const ef_env default_env_set[] = {
{"user", "user"},
};
static beken_semaphore_t env_cache_lock = NULL;
#ifdef PRINT_DEBUG
static char log_buf[256];
#endif
/**
* Flash port for hardware initialize.
*
* @param default_env default ENV set for user
* @param default_env_size default ENV size
*
* @return result
*/
EfErrCode ef_port_init(ef_env const **default_env, size_t *default_env_size)
{
bk_err_t ret;
EfErrCode result = EF_NO_ERR;
*default_env = default_env_set;
*default_env_size = sizeof(default_env_set) / sizeof(default_env_set[0]);
ret = rtos_init_semaphore_adv(&env_cache_lock, 1, 1);
BK_ASSERT(kNoErr == ret);
return result;
}
/**
* Read data from flash.
* @note This operation's units is word.
*
* @param addr flash address
* @param buf buffer to store read data
* @param size read bytes size
*
* @return result
*/
EfErrCode ef_port_read(uint32_t addr, uint32_t *buf, size_t size)
{
EfErrCode result = EF_NO_ERR;
EF_ASSERT(size % 4 == 0);
#if CONFIG_FLASH_ORIGIN_API
flash_read((char *)buf, (unsigned long)size, addr);
#else
bk_flash_read_bytes(addr, (uint8_t *)buf, (unsigned long)size);
#endif
return result;
}
/*
* size param: The flash size of you want to erase in bytes.
* return: Returns the size of the actual erase.
*/
static int bk_erase(uint32_t addr, size_t size)
{
#if CONFIG_FLASH_ORIGIN_API
int param;
UINT32 status;
int protect_type;
DD_HANDLE flash_handle;
#else
flash_protect_type_t protect_type;
#endif
unsigned int _size = size;
#if CONFIG_FLASH_ORIGIN_API
flash_handle = ddev_open(DD_DEV_TYPE_FLASH, &status, 0);
ddev_control(flash_handle, CMD_FLASH_GET_PROTECT, (void *)&protect_type);
if (FLASH_PROTECT_NONE != protect_type) {
param = FLASH_PROTECT_NONE;
ddev_control(flash_handle, CMD_FLASH_SET_PROTECT, (void *)&param);
}
#else
protect_type = bk_flash_get_protect_type();
if (FLASH_PROTECT_NONE != protect_type) {
bk_flash_set_protect_type(FLASH_PROTECT_NONE);
}
#endif
/* Calculate the start address of the flash sector(4kbytes) */
addr = addr & 0x00FFF000;
do {
#if CONFIG_FLASH_ORIGIN_API
flash_ctrl(CMD_FLASH_ERASE_SECTOR, &addr);
#else
bk_flash_erase_sector(addr);
#endif
addr += 4096;
if (_size < 4096)
_size = 0;
else
_size -= 4096;
} while (_size);
if (FLASH_PROTECT_NONE != protect_type) {
#if CONFIG_FLASH_ORIGIN_API
param = protect_type;
ddev_control(flash_handle, CMD_FLASH_SET_PROTECT, (void *)&param);
#else
bk_flash_set_protect_type(protect_type);
#endif
}
return size; // return true erase size
}
/**
* Erase data on flash.
* @note This operation is irreversible.
* @note This operation's units is different which on many chips.
*
* @param addr flash address
* @param size erase bytes size
*
* @return result
*/
EfErrCode ef_port_erase(uint32_t addr, size_t size)
{
EfErrCode result = EF_NO_ERR;
/* make sure the start address is a multiple of FLASH_ERASE_MIN_SIZE */
EF_ASSERT(addr % EF_ERASE_MIN_SIZE == 0);
bk_erase(addr, size);
return result;
}
/**
* Write data to flash.
* @note This operation's units is word.
* @note This operation must after erase. @see flash_erase.
*
* @param addr flash address
* @param buf the write data buffer
* @param size write bytes size
*
* @return result
*/
EfErrCode ef_port_write(uint32_t addr, const uint32_t *buf, size_t size)
{
#if CONFIG_FLASH_ORIGIN_API
int param;
UINT32 status;
int protect_type;
DD_HANDLE flash_handle;
#else
flash_protect_type_t protect_type;
#endif
EfErrCode result = EF_NO_ERR;
EF_ASSERT(size % 4 == 0);
#if CONFIG_FLASH_ORIGIN_API
flash_handle = ddev_open(DD_DEV_TYPE_FLASH, &status, 0);
ddev_control(flash_handle, CMD_FLASH_GET_PROTECT, (void *)&protect_type);
if (FLASH_PROTECT_NONE != protect_type) {
param = FLASH_PROTECT_NONE;
ddev_control(flash_handle, CMD_FLASH_SET_PROTECT, (void *)&param);
}
flash_write((char *)buf, (unsigned long)size, addr);
if (FLASH_PROTECT_NONE != protect_type) {
param = protect_type;
ddev_control(flash_handle, CMD_FLASH_SET_PROTECT, (void *)&param);
}
#else
protect_type = bk_flash_get_protect_type();
if (FLASH_PROTECT_NONE != protect_type) {
bk_flash_set_protect_type(FLASH_PROTECT_NONE);
}
bk_flash_write_bytes(addr, (const uint8_t *)buf, size);
bk_flash_set_protect_type(protect_type);
#endif
return result;
}
/**
* lock the ENV ram cache
*/
void ef_port_env_lock(void)
{
rtos_get_semaphore(&env_cache_lock, BEKEN_WAIT_FOREVER);
}
/**
* unlock the ENV ram cache
*/
void ef_port_env_unlock(void)
{
rtos_set_semaphore(&env_cache_lock);
}
/**
* This function is print flash debug info.
*
* @param file the file which has call this function
* @param line the line number which has call this function
* @param format output format
* @param ... args
*
*/
void ef_log_debug(const char *file, const long line, const char *format, ...)
{
#ifdef PRINT_DEBUG
va_list args;
/* args point to the first variable parameter */
va_start(args, format);
ef_print("[Flash](%s:%ld) ", file, line);
/* must use vprintf to print */
vsprintf(log_buf, format, args);
ef_print("%s", log_buf);
va_end(args);
#endif
}
/**
* This function is print flash routine info.
*
* @param format output format
* @param ... args
*/
void ef_log_info(const char *format, ...)
{
#ifdef PRINT_DEBUG
va_list args;
/* args point to the first variable parameter */
va_start(args, format);
ef_print("[Flash]");
/* must use vprintf to print */
vsprintf(log_buf, format, args);
ef_print("%s", log_buf);
va_end(args);
#endif
}
/**
* This function is print flash non-package info.
*
* @param format output format
* @param ... args
*/
void ef_print(const char *format, ...)
{
#ifdef PRINT_DEBUG
va_list args;
/* args point to the first variable parameter */
va_start(args, format);
/* must use vprintf to print */
vsprintf(log_buf, format, args);
os_printf("%s", log_buf);
va_end(args);
#endif
}
// eof
@@ -0,0 +1,100 @@
/*
* Copyright (c) 2014-2016, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: Initialize interface for this library.
* Created on: 2014-09-09
*/
/**
*
* This all Backup Area Flash storage index. All used flash area configure is under here.
* |----------------------------| Storage Size
* | Environment variables area | ENV area size @see ENV_AREA_SIZE
* | 1.system section | ENV system section size
* | 2:data section | ENV_AREA_SIZE - ENV system section size
* |----------------------------|
* | Saved log area | Log area size @see LOG_AREA_SIZE
* |----------------------------|
* |(IAP)Downloaded application | IAP already downloaded application, unfixed size
* |----------------------------|
*
* @note all area size must be aligned with EF_ERASE_MIN_SIZE
* @note EasyFlash will use ram to buffered the ENV. At some time flash's EF_ERASE_MIN_SIZE is so big,
* and you want use ENV size is less than it. So you must defined ENV_USER_SETTING_SIZE for ENV.
* @note ENV area size has some limitations in different modes.
* 1.Normal mode: no more limitations
* 2.Wear leveling mode: system section will used an flash section and the data section will used at least 2 flash sections
* 3.Power fail safeguard mode: ENV area will has an backup. It is twice as normal mode.
* 4.wear leveling and power fail safeguard mode: The required capacity will be 2 times the total capacity in wear leveling mode.
* For example:
* The EF_ERASE_MIN_SIZE is 128K and the ENV_USER_SETTING_SIZE: 2K. The ENV_AREA_SIZE in different mode you can define
* 1.Normal mode: 1*EF_ERASE_MIN_SIZE
* 2.Wear leveling mode: 3*EF_ERASE_MIN_SIZE (It has 2 data section to store ENV. So ENV can erase at least 200,000 times)
* 3.Power fail safeguard mode: 2*EF_ERASE_MIN_SIZE
* 4.Wear leveling and power fail safeguard mode: 6*EF_ERASE_MIN_SIZE
* @note the log area size must be more than twice of EF_ERASE_MIN_SIZE
*/
#include <easyflash.h>
/**
* EasyFlash system initialize.
*
* @return result
*/
EfErrCode easyflash_init(void)
{
extern EfErrCode ef_port_init(ef_env const **default_env, size_t *default_env_size);
extern EfErrCode ef_env_init(ef_env const * default_env, size_t default_env_size);
extern EfErrCode ef_iap_init(void);
extern EfErrCode ef_log_init(void);
size_t default_env_set_size = 0;
const ef_env *default_env_set;
EfErrCode result = EF_NO_ERR;
result = ef_port_init(&default_env_set, &default_env_set_size);
#ifdef EF_USING_ENV
if (result == EF_NO_ERR)
result = ef_env_init(default_env_set, default_env_set_size);
#endif
#ifdef EF_USING_IAP
if (result == EF_NO_ERR)
result = ef_iap_init();
#endif
#ifdef EF_USING_LOG
if (result == EF_NO_ERR)
result = ef_log_init();
#endif
if (result == EF_NO_ERR)
EF_INFO("EasyFlash V%s is initialize success.\n", EF_SW_VERSION);
else
EF_INFO("EasyFlash V%s is initialize fail.\n", EF_SW_VERSION);
EF_INFO("You can get the latest version on https://github.com/armink/EasyFlash .\n");
return result;
}
// eof
@@ -0,0 +1,812 @@
/*
* Copyright (c) 2014-2018, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: Environment variables operating interface. (normal mode)
* Created on: 2014-10-06
*/
#include <easyflash.h>
#include <string.h>
#include <stdlib.h>
#ifdef EF_USING_ENV
#ifndef EF_ENV_USING_WL_MODE
/**
* ENV area has 2 sections
* 1. System section
* It storage ENV parameters. (Units: Word)
* 2. Data section
* It storage all ENV. Storage format is key=value\0.
* All ENV must be 4 bytes alignment. The remaining part must fill '\0'.
*
* @note Word = 4 Bytes in this file
* @note It will has two ENV areas(Area0, Area1) when used power fail safeguard mode.
*/
/* flash ENV parameters index and size in system section */
enum {
/* data section ENV end address index in system section */
ENV_PARAM_INDEX_END_ADDR = 0,
#ifdef EF_ENV_USING_PFS_MODE
/* saved count for ENV area */
ENV_PARAM_INDEX_SAVED_COUNT,
#endif
/* data section CRC32 code index in system section */
ENV_PARAM_INDEX_DATA_CRC,
/* flash ENV parameters word size */
ENV_PARAM_WORD_SIZE,
/* flash ENV parameters byte size */
ENV_PARAM_BYTE_SIZE = ENV_PARAM_WORD_SIZE * 4,
};
/* default ENV set, must be initialized by user */
static ef_env const *default_env_set;
/* default ENV set size, must be initialized by user */
static size_t default_env_set_size = 0;
/* ENV ram cache */
static uint32_t env_cache[ENV_USER_SETTING_SIZE / 4] = { 0 };
/* ENV start address in flash */
static uint32_t env_start_addr = 0;
/* ENV ram cache has changed when ENV created, deleted and changed value. */
static bool env_cache_changed = false;
/* initialize OK flag */
static bool init_ok = false;
#ifdef EF_ENV_USING_PFS_MODE
/* current load ENV area address */
static uint32_t cur_load_area_addr = 0;
/* next save ENV area address */
static uint32_t next_save_area_addr = 0;
#endif
static uint32_t get_env_system_addr(void);
static uint32_t get_env_data_addr(void);
static uint32_t get_env_end_addr(void);
static void set_env_end_addr(uint32_t end_addr);
static EfErrCode write_env(const char *key, const char *value);
static char *find_env(const char *key);
static EfErrCode del_env(const char *key);
static size_t get_env_data_size(void);
static size_t get_env_user_used_size(void);
static EfErrCode create_env(const char *key, const char *value);
static uint32_t calc_env_crc(void);
static bool env_crc_is_ok(void);
/**
* Flash ENV initialize.
*
* @param default_env default ENV set for user
* @param default_env_size default ENV set size
*
* @note user_size must equal with total_size in normal mode
*
* @return result
*/
EfErrCode ef_env_init(ef_env const *default_env, size_t default_env_size)
{
EfErrCode result = EF_NO_ERR;
EF_ASSERT(ENV_AREA_SIZE);
EF_ASSERT(ENV_USER_SETTING_SIZE);
EF_ASSERT(EF_ERASE_MIN_SIZE);
/* must be word alignment for ENV */
EF_ASSERT(ENV_USER_SETTING_SIZE % 4 == 0);
EF_ASSERT(ENV_AREA_SIZE % 4 == 0);
EF_ASSERT(default_env);
EF_ASSERT(default_env_size < ENV_USER_SETTING_SIZE);
#ifndef EF_ENV_USING_PFS_MODE
/* total_size must be aligned with erase_min_size */
if (ENV_USER_SETTING_SIZE % EF_ERASE_MIN_SIZE == 0)
EF_ASSERT(ENV_USER_SETTING_SIZE == ENV_AREA_SIZE);
else
EF_ASSERT((ENV_USER_SETTING_SIZE / EF_ERASE_MIN_SIZE + 1)*EF_ERASE_MIN_SIZE == ENV_AREA_SIZE);
#else
/* total_size must be aligned with erase_min_size */
if (ENV_USER_SETTING_SIZE % EF_ERASE_MIN_SIZE == 0) {
/* it has double area when used power fail safeguard mode */
EF_ASSERT(2 * ENV_USER_SETTING_SIZE == ENV_AREA_SIZE);
} else {
/* it has double area when used power fail safeguard mode */
EF_ASSERT(2 * (ENV_USER_SETTING_SIZE / EF_ERASE_MIN_SIZE + 1)*EF_ERASE_MIN_SIZE == ENV_AREA_SIZE);
}
#endif
env_start_addr = EF_START_ADDR;
default_env_set = default_env;
default_env_set_size = default_env_size;
EF_DEBUG("ENV start address is 0x%08X, size is %d bytes.\n", EF_START_ADDR, ENV_AREA_SIZE);
result = ef_load_env();
if (result == EF_NO_ERR)
init_ok = true;
return result;
}
/**
* ENV set default.
*
* @return result
*/
EfErrCode ef_env_set_default(void)
{
EfErrCode result = EF_NO_ERR;
size_t i;
EF_ASSERT(default_env_set);
EF_ASSERT(default_env_set_size);
/* lock the ENV cache */
ef_port_env_lock();
/* set environment end address is at data section start address */
set_env_end_addr(get_env_data_addr());
#ifdef EF_ENV_USING_PFS_MODE
/* set saved count to default 0 */
env_cache[ENV_PARAM_INDEX_SAVED_COUNT] = 0;
#endif
/* create default ENV */
for (i = 0; i < default_env_set_size; i++)
create_env(default_env_set[i].key, default_env_set[i].value);
/* unlock the ENV cache */
ef_port_env_unlock();
result = ef_save_env();
#ifdef EF_ENV_USING_PFS_MODE
/* reset other PFS area's data */
if (result == EF_NO_ERR) {
env_cache_changed = true;
result = ef_save_env();
}
#endif
return result;
}
/**
* Get ENV system section start address.
*
* @return system section start address
*/
static uint32_t get_env_system_addr(void)
{
#ifndef EF_ENV_USING_PFS_MODE
return env_start_addr;
#else
return cur_load_area_addr;
#endif
}
/**
* Get ENV data section start address.
*
* @return data section start address
*/
static uint32_t get_env_data_addr(void)
{
return get_env_system_addr() + ENV_PARAM_BYTE_SIZE;
}
/**
* Get ENV end address.
* It's the first word in ENV.
*
* @return ENV end address
*/
static uint32_t get_env_end_addr(void)
{
/* it is the first word */
return env_cache[ENV_PARAM_INDEX_END_ADDR];
}
/**
* Set ENV end address.
* It's the first word in ENV.
*
* @param end_addr ENV end address
*/
static void set_env_end_addr(uint32_t end_addr)
{
env_cache[ENV_PARAM_INDEX_END_ADDR] = end_addr;
}
/**
* Get current ENV data section size.
*
* @return size
*/
static size_t get_env_data_size(void)
{
if (get_env_end_addr() > get_env_data_addr())
return get_env_end_addr() - get_env_data_addr();
else
return 0;
}
/**
* Get current user used ENV size.
*
* @return bytes
*/
static size_t get_env_user_used_size(void)
{
if (get_env_end_addr() > get_env_system_addr())
return get_env_end_addr() - get_env_system_addr();
else
return 0;
}
/**
* Get current ENV already write bytes.
*
* @return write bytes
*/
size_t ef_get_env_write_bytes(void)
{
#ifndef EF_ENV_USING_PFS_MODE
return get_env_user_used_size();
#else
return get_env_user_used_size() * 2;
#endif
}
/**
* Write an ENV at the end of cache.
*
* @param key ENV name
* @param value ENV value
*
* @return result
*/
static EfErrCode write_env(const char *key, const char *value)
{
EfErrCode result = EF_NO_ERR;
size_t key_len = strlen(key), value_len = strlen(value), env_str_len;
char *env_cache_bak = (char *)env_cache;
/* calculate ENV storage length, contain '=' and '\0'. */
env_str_len = key_len + value_len + 2;
if (env_str_len % 4 != 0)
env_str_len = (env_str_len / 4 + 1) * 4;
/* check capacity of ENV */
if (env_str_len + get_env_user_used_size() >= ENV_USER_SETTING_SIZE)
return EF_ENV_FULL;
/* calculate current ENV ram cache end address */
env_cache_bak += get_env_user_used_size();
/* copy key name */
memmove(env_cache_bak, key, key_len);
env_cache_bak += key_len;
/* copy equal sign */
*env_cache_bak = '=';
env_cache_bak++;
/* copy value */
memmove(env_cache_bak, value, value_len);
env_cache_bak += value_len;
/* fill '\0' for string end sign */
*env_cache_bak = '\0';
env_cache_bak ++;
/* fill '\0' for word alignment */
memset(env_cache_bak, 0, env_str_len - (key_len + value_len + 2));
set_env_end_addr(get_env_end_addr() + env_str_len);
/* ENV ram cache has changed */
env_cache_changed = true;
return result;
}
/**
* Find ENV.
*
* @param key ENV name
*
* @return found ENV in ram cache
*/
static char *find_env(const char *key)
{
char *env_start, *env_end, *env, *found_env = NULL;
size_t key_len = strlen(key), env_len;
if ((key == NULL) || (*key == 0)) {
EF_INFO("Flash ENV name must be not empty!\n");
return NULL;
}
/* from data section start to data section end */
env_start = (char *)((char *) env_cache + ENV_PARAM_BYTE_SIZE);
env_end = (char *)((char *) env_cache + get_env_user_used_size());
/* ENV is null */
if (env_start == env_end)
return NULL;
env = env_start;
while (env < env_end) {
/* the key length must be equal */
if (!strncmp(env, key, key_len) && (env[key_len] == '=')) {
found_env = env;
break;
} else {
/* calculate ENV length, contain '\0'. */
env_len = strlen(env) + 1;
/* next ENV and word alignment */
if (env_len % 4 == 0)
env += env_len;
else
env += (env_len / 4 + 1) * 4;
}
}
return found_env;
}
/**
* If the ENV is not exist, create it.
* @see flash_write_env
*
* @param key ENV name
* @param value ENV value
*
* @return result
*/
static EfErrCode create_env(const char *key, const char *value)
{
EfErrCode result = EF_NO_ERR;
EF_ASSERT(key);
EF_ASSERT(value);
if ((key == NULL) || (*key == 0)) {
EF_INFO("Flash ENV name must be not empty!\n");
return EF_ENV_NAME_ERR;
}
if (strchr(key, '=')) {
EF_INFO("Flash ENV name can't contain '='.\n");
return EF_ENV_NAME_ERR;
}
/* find ENV */
if (find_env(key)) {
EF_INFO("The name of \"%s\" is already exist.\n", key);
return EF_ENV_NAME_EXIST;
}
/* write ENV at the end of cache */
result = write_env(key, value);
return result;
}
/**
* Delete an ENV in cache.
*
* @param key ENV name
*
* @return result
*/
static EfErrCode del_env(const char *key)
{
EfErrCode result = EF_NO_ERR;
char *del_env = NULL;
size_t del_env_length, remain_env_length;
EF_ASSERT(key);
if ((key == NULL) || (*key == 0)) {
EF_INFO("Flash ENV name must be not NULL!\n");
return EF_ENV_NAME_ERR;
}
if (strchr(key, '=')) {
EF_INFO("Flash ENV name or value can't contain '='.\n");
return EF_ENV_NAME_ERR;
}
/* find ENV */
del_env = find_env(key);
if (!del_env) {
EF_INFO("Not find \"%s\" in ENV.\n", key);
return EF_ENV_NAME_ERR;
}
del_env_length = strlen(del_env);
/* '\0' also must be as ENV length */
del_env_length ++;
/* the address must multiple of 4 */
if (del_env_length % 4 != 0)
del_env_length = (del_env_length / 4 + 1) * 4;
/* calculate remain ENV length */
remain_env_length = get_env_data_size()
- (((uint32_t) del_env + del_env_length) - ((uint32_t) env_cache + ENV_PARAM_BYTE_SIZE));
/* remain ENV move forward */
memmove(del_env, del_env + del_env_length, remain_env_length);
/* reset ENV end address */
set_env_end_addr(get_env_end_addr() - del_env_length);
/* ENV ram cache has changed */
env_cache_changed = true;
return result;
}
/**
* Set an ENV. If it value is empty, delete it.
* If not find it in ENV table, then create it.
*
* @param key ENV name
* @param value ENV value
*
* @return result
*/
EfErrCode ef_set_env(const char *key, const char *value)
{
EfErrCode result = EF_NO_ERR;
char *old_env, *old_value;
if (!init_ok) {
EF_INFO("ENV isn't initialize OK.\n");
return EF_ENV_INIT_FAILED;
}
/* lock the ENV cache */
ef_port_env_lock();
/* if ENV value is empty, delete it */
if ((value == NULL) || (*value == 0))
result = del_env(key);
else {
old_env = find_env(key);
/* If find this ENV, then compare the new value and old value. */
if (old_env) {
/* find the old value address */
old_env = strchr(old_env, '=');
old_value = old_env + 1;
/* If it is changed then delete it and recreate it */
if (strcmp(old_value, value)) {
result = del_env(key);
if (result == EF_NO_ERR)
result = create_env(key, value);
}
} else
result = create_env(key, value);
}
/* unlock the ENV cache */
ef_port_env_unlock();
return result;
}
/**
* Get an ENV value by key name.
*
* @param key ENV name
*
* @return value
*/
char *ef_get_env(const char *key)
{
char *env = NULL, *value = NULL;
if (!init_ok) {
EF_INFO("ENV isn't initialize OK.\n");
return NULL;
}
/* find ENV */
env = find_env(key);
if (env == NULL)
return NULL;
/* get value address */
value = strchr(env, '=');
if (value != NULL) {
/* the equal sign next character is value */
value++;
}
return value;
}
/**
* Print ENV.
*/
void ef_print_env(void)
{
uint32_t *env_cache_data_addr = env_cache + ENV_PARAM_WORD_SIZE,
*env_cache_end_addr =
(uint32_t *)(env_cache + ENV_PARAM_WORD_SIZE + get_env_data_size() / 4);
uint8_t j;
char c;
if (!init_ok) {
EF_INFO("ENV isn't initialize OK.\n");
return;
}
for (; env_cache_data_addr < env_cache_end_addr; env_cache_data_addr += 1) {
for (j = 0; j < 4; j++) {
c = (*env_cache_data_addr) >> (8 * j);
ef_print("%c", c);
if (c == 0) {
ef_print("\n");
break;
}
}
}
#ifndef EF_ENV_USING_PFS_MODE
ef_print("\nENV size: %ld/%ld bytes.\n", get_env_user_used_size(), ENV_USER_SETTING_SIZE);
#else
ef_print("\nENV size: %ld/%ld bytes, write bytes %ld/%ld, saved count: %ld, mode: power fail safeguard.\n",
get_env_user_used_size(), ENV_USER_SETTING_SIZE, ef_get_env_write_bytes(),
ENV_AREA_SIZE, env_cache[ENV_PARAM_INDEX_SAVED_COUNT]);
#endif
}
/**
* Load flash ENV to ram.
*
* @return result
*/
#ifndef EF_ENV_USING_PFS_MODE
EfErrCode ef_load_env(void)
{
EfErrCode result = EF_NO_ERR;
uint32_t *env_cache_bak, env_end_addr;
/* read ENV end address from flash */
ef_port_read(get_env_system_addr() + ENV_PARAM_INDEX_END_ADDR * 4, &env_end_addr, 4);
/* if ENV is not initialize or flash has dirty data, set default for it */
if ((env_end_addr == 0xFFFFFFFF) || (env_end_addr < env_start_addr)
|| (env_end_addr > env_start_addr + ENV_USER_SETTING_SIZE))
result = ef_env_set_default();
else {
/* set ENV end address */
set_env_end_addr(env_end_addr);
env_cache_bak = env_cache + ENV_PARAM_WORD_SIZE;
/* read all ENV from flash */
ef_port_read(get_env_data_addr(), env_cache_bak, get_env_data_size());
/* read ENV CRC code from flash */
ef_port_read(get_env_system_addr() + ENV_PARAM_INDEX_DATA_CRC * 4,
&env_cache[ENV_PARAM_INDEX_DATA_CRC], 4);
/* if ENV CRC32 check is fault, set default for it */
if (!env_crc_is_ok()) {
EF_INFO("Warning: ENV CRC check failed. Set it to default.\n");
result = ef_env_set_default();
}
}
return result;
}
#else
EfErrCode ef_load_env(void)
{
EfErrCode result = EF_NO_ERR;
uint32_t area0_start_address = env_start_addr, area1_start_address = env_start_addr
+ ENV_AREA_SIZE / 2;
uint32_t area0_end_addr, area1_end_addr, area0_crc, area1_crc, area0_saved_count, area1_saved_count;
bool area0_is_valid = true, area1_is_valid = true;
/* read ENV area end address from flash */
ef_port_read(area0_start_address + ENV_PARAM_INDEX_END_ADDR * 4, &area0_end_addr, 4);
ef_port_read(area1_start_address + ENV_PARAM_INDEX_END_ADDR * 4, &area1_end_addr, 4);
if ((area0_end_addr == 0xFFFFFFFF) || (area0_end_addr < area0_start_address)
|| (area0_end_addr > area0_start_address + ENV_USER_SETTING_SIZE))
area0_is_valid = false;
if ((area1_end_addr == 0xFFFFFFFF) || (area1_end_addr < area1_start_address)
|| (area1_end_addr > area1_start_address + ENV_USER_SETTING_SIZE))
area1_is_valid = false;
/* check area0 CRC when it is valid */
if (area0_is_valid) {
/* read ENV area0 crc32 code from flash */
ef_port_read(area0_start_address + ENV_PARAM_INDEX_DATA_CRC * 4, &area0_crc, 4);
/* read ENV from ENV area0 */
ef_port_read(area0_start_address, env_cache, area0_end_addr - area0_start_address);
/* current load ENV area address is area0 start address */
cur_load_area_addr = area0_start_address;
if (!env_crc_is_ok())
area0_is_valid = false;
}
/* check area1 CRC when it is valid */
if (area1_is_valid) {
/* read ENV area1 crc32 code from flash */
ef_port_read(area1_start_address + ENV_PARAM_INDEX_DATA_CRC * 4, &area1_crc, 4);
/* read ENV from ENV area1 */
ef_port_read(area1_start_address, env_cache, area1_end_addr - area1_start_address);
/* current load ENV area address is area1 start address */
cur_load_area_addr = area1_start_address;
if (!env_crc_is_ok())
area1_is_valid = false;
}
/* all ENV area CRC is OK then compare saved count */
if (area0_is_valid && area1_is_valid) {
/* read ENV area saved count from flash */
ef_port_read(area0_start_address + ENV_PARAM_INDEX_SAVED_COUNT * 4,
&area0_saved_count, 4);
ef_port_read(area1_start_address + ENV_PARAM_INDEX_SAVED_COUNT * 4,
&area1_saved_count, 4);
/* the bigger saved count area is valid */
if ((area0_saved_count > area1_saved_count) || ((area0_saved_count == 0) && (area1_saved_count == 0xFFFFFFFF)))
area1_is_valid = false;
else
area0_is_valid = false;
}
if (area0_is_valid) {
/* current load ENV area address is area0 start address */
cur_load_area_addr = area0_start_address;
/* next save ENV area address is area1 start address */
next_save_area_addr = area1_start_address;
/* read all ENV from area0 */
ef_port_read(area0_start_address, env_cache, area0_end_addr - area0_start_address);
} else if (area1_is_valid) {
/* next save ENV area address is area0 start address */
next_save_area_addr = area0_start_address;
} else {
/* current load ENV area address is area1 start address */
cur_load_area_addr = area1_start_address;
/* next save ENV area address is area0 start address */
next_save_area_addr = area0_start_address;
/* set the ENV to default */
result = ef_env_set_default();
}
return result;
}
#endif
/**
* Save ENV to flash.
*/
EfErrCode ef_save_env(void)
{
EfErrCode result = EF_NO_ERR;
uint32_t write_addr, write_size;
/* ENV ram cache has not changed don't need to save */
if (!env_cache_changed)
return result;
#ifndef EF_ENV_USING_PFS_MODE
write_addr = get_env_system_addr();
write_size = get_env_user_used_size();
/* calculate and cache CRC32 code */
env_cache[ENV_PARAM_INDEX_DATA_CRC] = calc_env_crc();
#else
write_addr = next_save_area_addr;
write_size = get_env_user_used_size();
/* replace next_save_area_addr with cur_load_area_addr */
next_save_area_addr = cur_load_area_addr;
cur_load_area_addr = write_addr;
/* change the ENV end address to next save area address */
set_env_end_addr(write_addr + write_size);
/* ENV area saved count +1 */
env_cache[ENV_PARAM_INDEX_SAVED_COUNT]++;
/* calculate and cache CRC32 code */
env_cache[ENV_PARAM_INDEX_DATA_CRC] = calc_env_crc();
#endif
/* erase ENV */
result = ef_port_erase(write_addr, write_size);
switch (result) {
case EF_NO_ERR: {
EF_INFO("Erased ENV OK.\n");
break;
}
case EF_ERASE_ERR: {
EF_INFO("Error: Erased ENV fault! Start address is 0x%08X, size is %ld.\n", write_addr, write_size);
/* will return when erase fault */
return result;
}
default:
break;
}
/* write ENV to flash */
result = ef_port_write(write_addr, env_cache, write_size);
switch (result) {
case EF_NO_ERR: {
EF_INFO("Saved ENV OK.\n");
break;
}
case EF_WRITE_ERR: {
EF_INFO("Error: Saved ENV fault! Start address is 0x%08X, size is %ld.\n", write_addr, write_size);
break;
}
default:
break;
}
env_cache_changed = false;
return result;
}
/**
* Calculate the cached ENV CRC32 value.
*
* @return CRC32 value
*/
static uint32_t calc_env_crc(void)
{
uint32_t crc32 = 0;
/* Calculate the ENV end address CRC32. The 4 is ENV end address bytes size. */
crc32 = ef_calc_crc32(crc32, &env_cache[ENV_PARAM_INDEX_END_ADDR], 4);
#ifdef EF_ENV_USING_PFS_MODE
/* Calculate the ENV area saved count CRC32. */
crc32 = ef_calc_crc32(crc32, &env_cache[ENV_PARAM_INDEX_SAVED_COUNT], 4);
#endif
/* Calculate the all ENV data CRC32. */
crc32 = ef_calc_crc32(crc32, &env_cache[ENV_PARAM_WORD_SIZE], get_env_data_size());
EF_DEBUG("Calculate ENV CRC32 number is 0x%08X.\n", crc32);
return crc32;
}
/**
* Check the ENV CRC32
*
* @return true is ok
*/
static bool env_crc_is_ok(void)
{
if (calc_env_crc() == env_cache[ENV_PARAM_INDEX_DATA_CRC]) {
EF_DEBUG("Verify ENV CRC32 result is OK.\n");
return true;
} else
return false;
}
/**
* Set and save an ENV. If set ENV is success then will save it.
*
* @param key ENV name
* @param value ENV value
*
* @return result
*/
EfErrCode ef_set_and_save_env(const char *key, const char *value)
{
EfErrCode result = EF_NO_ERR;
result = ef_set_env(key, value);
if (result == EF_NO_ERR)
result = ef_save_env();
return result;
}
#endif /* EF_ENV_USING_WL_MODE */
#endif /* EF_USING_ENV */
@@ -0,0 +1,971 @@
/*
* Copyright (c) 2015-2018, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: Environment variables operating interface. (wear leveling mode)
* Created on: 2015-02-11
*/
#include <easyflash.h>
#include <string.h>
#include <stdlib.h>
#ifdef EF_USING_ENV
#ifdef EF_ENV_USING_WL_MODE
/**
* ENV area has 2 sections
* 1. System section
* Storage ENV current using data section address.
* Units: Word. Total size: @see EF_ERASE_MIN_SIZE.
* 2. Data section
* The data section storage ENV's parameters and detail.
* When an exception has occurred on flash erase or write. The current using data section
* address will move to next available position. This position depends on EF_ERASE_MIN_SIZE.
* 2.1 ENV parameters part
* It storage ENV's parameters.
* 2.2 ENV detail part
* It storage all ENV. Storage format is key=value\0.
* All ENV must be 4 bytes alignment. The remaining part must fill '\0'.
*
* @note Word = 4 Bytes in this file
* @note It will has two ENV areas(Area0, Area1) in data section when used power fail safeguard mode.
*/
/* flash ENV parameters part index and size */
enum {
/* data section ENV detail part end address index */
ENV_PARAM_PART_INDEX_END_ADDR = 0,
#ifdef EF_ENV_USING_PFS_MODE
/* saved count for ENV area */
ENV_PARAM_PART_INDEX_SAVED_COUNT,
#endif
/* data section CRC32 code index */
ENV_PARAM_PART_INDEX_DATA_CRC,
/* ENV parameters part word size */
ENV_PARAM_PART_WORD_SIZE,
/* ENV parameters part byte size */
ENV_PARAM_PART_BYTE_SIZE = ENV_PARAM_PART_WORD_SIZE * 4,
};
/* default ENV set, must be initialized by user */
static ef_env const *default_env_set;
/* default ENV set size, must be initialized by user */
static size_t default_env_set_size = 0;
/* flash ENV data section size */
static size_t env_data_section_size = 0;
/* ENV ram cache */
static uint32_t env_cache[ENV_USER_SETTING_SIZE / 4] = { 0 };
/* ENV start address in flash */
static uint32_t env_start_addr = 0;
/* current using data section address */
static uint32_t cur_using_data_addr = 0;
/* ENV ram cache has changed when ENV created, deleted and changed value. */
static bool env_cache_changed = false;
/* initialize OK flag */
static bool init_ok = false;
#ifdef EF_ENV_USING_PFS_MODE
/* next save ENV area address */
static uint32_t next_save_area_addr = 0;
#endif
static uint32_t get_env_start_addr(void);
static uint32_t get_cur_using_data_addr(void);
static uint32_t get_env_detail_addr(void);
static uint32_t get_env_detail_end_addr(void);
static void set_cur_using_data_addr(uint32_t using_data_addr);
static void set_env_detail_end_addr(uint32_t end_addr);
static EfErrCode write_env(const char *key, const char *value);
static char *find_env(const char *key);
static size_t get_env_detail_size(void);
static size_t get_env_user_used_size(void);
static EfErrCode create_env(const char *key, const char *value);
static EfErrCode del_env(const char *key);
static EfErrCode save_cur_using_data_addr(uint32_t cur_data_addr);
static uint32_t calc_env_crc(void);
static bool env_crc_is_ok(void);
/**
* Flash ENV initialize.
*
* @param default_env default ENV set for user
* @param default_env_size default ENV set size
*
* @return result
*/
EfErrCode ef_env_init(ef_env const *default_env, size_t default_env_size)
{
EfErrCode result = EF_NO_ERR;
EF_ASSERT(ENV_AREA_SIZE);
EF_ASSERT(ENV_USER_SETTING_SIZE);
/* must be word alignment for ENV */
EF_ASSERT(ENV_USER_SETTING_SIZE % 4 == 0);
EF_ASSERT(ENV_AREA_SIZE % 4 == 0);
EF_ASSERT(default_env);
EF_ASSERT(default_env_size < ENV_USER_SETTING_SIZE);
#ifndef EF_ENV_USING_PFS_MODE
/* system section size is erase_min_size, so last part is data section */
env_data_section_size = ENV_AREA_SIZE - EF_ERASE_MIN_SIZE;
#else
/* system section size is erase_min_size, so last part is data section */
env_data_section_size = ENV_AREA_SIZE / 2 - EF_ERASE_MIN_SIZE;
EF_ASSERT((ENV_AREA_SIZE / EF_ERASE_MIN_SIZE) % 2 == 0);
#endif
EF_ASSERT(env_data_section_size >= ENV_USER_SETTING_SIZE);
/* the ENV data section size should be an integral multiple of erase minimum size. */
EF_ASSERT(env_data_section_size % EF_ERASE_MIN_SIZE == 0);
env_start_addr = EF_START_ADDR;
default_env_set = default_env;
default_env_set_size = default_env_size;
EF_DEBUG("ENV start address is 0x%08X, size is %d bytes.\n", EF_START_ADDR, ENV_AREA_SIZE);
result = ef_load_env();
if (result == EF_NO_ERR)
init_ok = true;
return result;
}
/**
* ENV set default.
*
* @return result
*/
EfErrCode ef_env_set_default(void)
{
EfErrCode result = EF_NO_ERR;
size_t i;
EF_ASSERT(default_env_set);
EF_ASSERT(default_env_set_size);
/* lock the ENV cache */
ef_port_env_lock();
/* set ENV detail part end address is at ENV detail part start address */
set_env_detail_end_addr(get_env_detail_addr());
#ifdef EF_ENV_USING_PFS_MODE
/* set saved count to default 0 */
env_cache[ENV_PARAM_PART_INDEX_SAVED_COUNT] = 0;
#endif
/* create default ENV */
for (i = 0; i < default_env_set_size; i++)
create_env(default_env_set[i].key, default_env_set[i].value);
/* unlock the ENV cache */
ef_port_env_unlock();
result = ef_save_env();
#ifdef EF_ENV_USING_PFS_MODE
/* reset other PFS area's data */
if (result == EF_NO_ERR) {
env_cache_changed = true;
result = ef_save_env();
}
#endif
return result;
}
/**
* Get ENV start address in flash.
*
* @return ENV start address in flash
*/
static uint32_t get_env_start_addr(void)
{
return env_start_addr;
}
/**
* Get current using data section address.
*
* @return current using data section address
*/
static uint32_t get_cur_using_data_addr(void)
{
return cur_using_data_addr;
}
/**
* Set current using data section address.
*
* @param using_data_addr current using data section address
*/
static void set_cur_using_data_addr(uint32_t using_data_addr)
{
cur_using_data_addr = using_data_addr;
}
/**
* Get ENV detail part start address.
*
* @return detail part start address
*/
static uint32_t get_env_detail_addr(void)
{
return get_cur_using_data_addr() + ENV_PARAM_PART_BYTE_SIZE;
}
/**
* Get ENV detail part end address.
* It's the first word in ENV.
*
* @return ENV end address
*/
static uint32_t get_env_detail_end_addr(void)
{
/* it is the first word */
return env_cache[ENV_PARAM_PART_INDEX_END_ADDR];
}
/**
* Set ENV detail part end address.
* It's the first word in ENV.
*
* @param end_addr ENV end address
*/
static void set_env_detail_end_addr(uint32_t end_addr)
{
env_cache[ENV_PARAM_PART_INDEX_END_ADDR] = end_addr;
}
/**
* Get current ENV detail part size.
*
* @return size
*/
static size_t get_env_detail_size(void)
{
if (get_env_detail_end_addr() > get_env_detail_addr())
return get_env_detail_end_addr() - get_env_detail_addr();
else
return 0;
}
/**
* Get current user used ENV size.
*
* @see ENV_USER_SETTING_SIZE
*
* @return size
*/
/* must be initialized */
static size_t get_env_user_used_size(void)
{
if (get_env_detail_end_addr() > get_cur_using_data_addr())
return get_env_detail_end_addr() - get_cur_using_data_addr();
else
return 0;
}
/**
* Get current ENV already write bytes.
*
* @return write bytes
*/
size_t ef_get_env_write_bytes(void)
{
#ifndef EF_ENV_USING_PFS_MODE
return get_env_detail_end_addr() - get_env_start_addr();
#else
return EF_ERASE_MIN_SIZE + get_env_detail_end_addr() - get_cur_using_data_addr();
#endif
}
/**
* Write an ENV at the end of cache.
*
* @param key ENV name
* @param value ENV value
*
* @return result
*/
static EfErrCode write_env(const char *key, const char *value)
{
EfErrCode result = EF_NO_ERR;
size_t ker_len = strlen(key), value_len = strlen(value), env_str_len;
char *env_cache_bak = (char *)env_cache;
/* calculate ENV storage length, contain '=' and '\0'. */
env_str_len = ker_len + value_len + 2;
if (env_str_len % 4 != 0)
env_str_len = (env_str_len / 4 + 1) * 4;
/* check capacity of ENV */
if (env_str_len + get_env_user_used_size() >= ENV_USER_SETTING_SIZE)
return EF_ENV_FULL;
/* calculate current ENV ram cache end address */
env_cache_bak += ENV_PARAM_PART_BYTE_SIZE + get_env_detail_size();
/* copy key name */
memcpy(env_cache_bak, key, ker_len);
env_cache_bak += ker_len;
/* copy equal sign */
*env_cache_bak = '=';
env_cache_bak++;
/* copy value */
memcpy(env_cache_bak, value, value_len);
env_cache_bak += value_len;
/* fill '\0' for string end sign */
*env_cache_bak = '\0';
env_cache_bak ++;
/* fill '\0' for word alignment */
memset(env_cache_bak, 0, env_str_len - (ker_len + value_len + 2));
set_env_detail_end_addr(get_env_detail_end_addr() + env_str_len);
/* ENV ram cache has changed */
env_cache_changed = true;
return result;
}
/**
* Find ENV.
*
* @param key ENV name
*
* @return found ENV in ram cache
*/
static char *find_env(const char *key)
{
char *env_start, *env_end, *env, *found_env = NULL;
size_t key_len = strlen(key), env_len;
if (*key == NULL) {
EF_INFO("Flash ENV name must be not empty!\n");
return NULL;
}
/* from data section start to data section end */
env_start = (char *)((char *) env_cache + ENV_PARAM_PART_BYTE_SIZE);
env_end = (char *)((char *) env_cache + ENV_PARAM_PART_BYTE_SIZE + get_env_detail_size());
/* ENV is null */
if (env_start == env_end)
return NULL;
env = env_start;
while (env < env_end) {
/* the key length must be equal */
if (!strncmp(env, key, key_len) && (env[key_len] == '=')) {
found_env = env;
break;
} else {
/* calculate ENV length, contain '\0'. */
env_len = strlen(env) + 1;
/* next ENV and word alignment */
if (env_len % 4 == 0)
env += env_len;
else
env += (env_len / 4 + 1) * 4;
}
}
return found_env;
}
/**
* If the ENV is not exist, create it.
* @see flash_write_env
*
* @param key ENV name
* @param value ENV value
*
* @return result
*/
static EfErrCode create_env(const char *key, const char *value)
{
EfErrCode result = EF_NO_ERR;
EF_ASSERT(key);
EF_ASSERT(value);
if (*key == NULL) {
EF_INFO("Flash ENV name must be not empty!\n");
return EF_ENV_NAME_ERR;
}
if (strchr(key, '=')) {
EF_INFO("Flash ENV name can't contain '='.\n");
return EF_ENV_NAME_ERR;
}
/* find ENV */
if (find_env(key)) {
EF_INFO("The name of \"%s\" is already exist.\n", key);
return EF_ENV_NAME_EXIST;
}
/* write ENV at the end of cache */
result = write_env(key, value);
return result;
}
/**
* Delete an ENV in cache.
*
* @param key ENV name
*
* @return result
*/
static EfErrCode del_env(const char *key)
{
EfErrCode result = EF_NO_ERR;
char *del_env = NULL;
size_t del_env_length, remain_env_length;
EF_ASSERT(key);
if (*key == NULL) {
EF_INFO("Flash ENV name must be not NULL!\n");
return EF_ENV_NAME_ERR;
}
if (strchr(key, '=')) {
EF_INFO("Flash ENV name or value can't contain '='.\n");
return EF_ENV_NAME_ERR;
}
/* find ENV */
del_env = find_env(key);
if (!del_env) {
EF_INFO("Not find \"%s\" in ENV.\n", key);
return EF_ENV_NAME_ERR;
}
del_env_length = strlen(del_env);
/* '\0' also must be as ENV length */
del_env_length ++;
/* the address must multiple of 4 */
if (del_env_length % 4 != 0)
del_env_length = (del_env_length / 4 + 1) * 4;
/* calculate remain ENV length */
remain_env_length = get_env_detail_size()
- (((uint32_t) del_env + del_env_length) - ((uint32_t) env_cache + ENV_PARAM_PART_BYTE_SIZE));
/* remain ENV move forward */
memcpy(del_env, del_env + del_env_length, remain_env_length);
/* reset ENV end address */
set_env_detail_end_addr(get_env_detail_end_addr() - del_env_length);
/* ENV ram cache has changed */
env_cache_changed = true;
return result;
}
/**
* Set an ENV. If it value is empty, delete it.
* If not find it in ENV table, then create it.
*
* @param key ENV name
* @param value ENV value
*
* @return result
*/
EfErrCode ef_set_env(const char *key, const char *value)
{
EfErrCode result = EF_NO_ERR;
char *old_env, *old_value;
if (!init_ok) {
EF_INFO("ENV isn't initialize OK.\n");
return EF_ENV_INIT_FAILED;
}
/* lock the ENV cache */
ef_port_env_lock();
/* if ENV value is empty, delete it */
if (*value == NULL)
result = del_env(key);
else {
old_env = find_env(key);
/* If find this ENV, then compare the new value and old value. */
if (old_env) {
/* find the old value address */
old_env = strchr(old_env, '=');
old_value = old_env + 1;
/* If it is changed then delete it and recreate it */
if (strcmp(old_value, value)) {
result = del_env(key);
if (result == EF_NO_ERR)
result = create_env(key, value);
}
} else
result = create_env(key, value);
}
/* unlock the ENV cache */
ef_port_env_unlock();
return result;
}
/**
* Get an ENV value by key name.
*
* @param key ENV name
*
* @return value
*/
char *ef_get_env(const char *key)
{
char *env = NULL, *value = NULL;
if (!init_ok) {
EF_INFO("ENV isn't initialize OK.\n");
return NULL;
}
/* find ENV */
env = find_env(key);
if (env == NULL)
return NULL;
/* get value address */
value = strchr(env, '=');
if (value != NULL) {
/* the equal sign next character is value */
value++;
}
return value;
}
/**
* Print ENV.
*/
void ef_print_env(void)
{
uint32_t *env_cache_detail_addr = env_cache + ENV_PARAM_PART_WORD_SIZE, *env_cache_end_addr =
(uint32_t *)(env_cache + ENV_PARAM_PART_WORD_SIZE + get_env_detail_size() / 4);
uint8_t j;
char c;
if (!init_ok) {
EF_INFO("ENV isn't initialize OK.\n");
return;
}
for (; env_cache_detail_addr < env_cache_end_addr; env_cache_detail_addr += 1) {
for (j = 0; j < 4; j++) {
c = (*env_cache_detail_addr) >> (8 * j);
ef_print("%c", c);
if (c == NULL) {
ef_print("\n");
break;
}
}
}
#ifndef EF_ENV_USING_PFS_MODE
ef_print("\nENV size: %ld/%ld bytes, write bytes %ld/%ld, mode: wear leveling.\n",
get_env_user_used_size(), ENV_USER_SETTING_SIZE, ef_get_env_write_bytes(),
ENV_AREA_SIZE);
#else
ef_print("\nENV size: %ld/%ld bytes, write bytes %ld/%ld, saved count: %ld, mode: wear leveling and power fail safeguard.\n",
get_env_user_used_size(), ENV_USER_SETTING_SIZE, ef_get_env_write_bytes(),
ENV_AREA_SIZE / 2, env_cache[ENV_PARAM_PART_INDEX_SAVED_COUNT]);
#endif
}
/**
* Load flash ENV to ram.
*
* @return result
*/
#ifndef EF_ENV_USING_PFS_MODE
EfErrCode ef_load_env(void)
{
EfErrCode result = EF_NO_ERR;
uint32_t *env_cache_bak, env_end_addr, using_data_addr;
/* read current using data section address */
ef_port_read(get_env_start_addr(), &using_data_addr, 4);
/* if ENV is not initialize or flash has dirty data, set default for it */
if ((using_data_addr == 0xFFFFFFFF)
|| (using_data_addr > get_env_start_addr() + ENV_AREA_SIZE)
|| (using_data_addr < get_env_start_addr() + EF_ERASE_MIN_SIZE)) {
/* initialize current using data section address */
set_cur_using_data_addr(get_env_start_addr() + EF_ERASE_MIN_SIZE);
/* save current using data section address to flash*/
if ((result = save_cur_using_data_addr(get_cur_using_data_addr())) == EF_NO_ERR) {
/* set default ENV */
result = ef_env_set_default();
}
} else {
/* set current using data section address */
set_cur_using_data_addr(using_data_addr);
/* read ENV detail part end address from flash */
ef_port_read(get_cur_using_data_addr() + ENV_PARAM_PART_INDEX_END_ADDR * 4, &env_end_addr, 4);
/* if ENV end address has error, set default for ENV */
if (env_end_addr > get_env_start_addr() + ENV_AREA_SIZE) {
/* initialize current using data section address */
set_cur_using_data_addr(get_env_start_addr() + EF_ERASE_MIN_SIZE);
/* save current using data section address to flash*/
if ((result = save_cur_using_data_addr(get_cur_using_data_addr())) == EF_NO_ERR) {
EF_INFO("Warning: ENV end address has error. Set it to default.\n");
result = ef_env_set_default();
}
} else {
/* set ENV detail part end address */
set_env_detail_end_addr(env_end_addr);
env_cache_bak = env_cache + ENV_PARAM_PART_WORD_SIZE;
/* read all ENV from flash */
ef_port_read(get_env_detail_addr(), env_cache_bak, get_env_detail_size());
/* read ENV CRC code from flash */
ef_port_read(get_cur_using_data_addr() + ENV_PARAM_PART_INDEX_DATA_CRC * 4,
&env_cache[ENV_PARAM_PART_INDEX_DATA_CRC], 4);
/* if ENV CRC32 check is fault, set default for it */
if (!env_crc_is_ok()) {
EF_INFO("Warning: ENV CRC check failed. Set it to default.\n");
result = ef_env_set_default();
}
}
}
return result;
}
#else
EfErrCode ef_load_env(void)
{
EfErrCode result = EF_NO_ERR;
/* ENV area0 current using address default value */
uint32_t area0_default_cur_using_addr = get_env_start_addr() + EF_ERASE_MIN_SIZE;
/* ENV area1 current using address default value */
uint32_t area1_default_cur_using_addr = area0_default_cur_using_addr + ENV_AREA_SIZE / 2;
uint32_t area0_cur_using_addr, area1_cur_using_addr, area0_end_addr, area1_end_addr;
uint32_t area0_crc, area1_crc, area0_saved_count, area1_saved_count;
bool area0_is_valid = true, area1_is_valid = true;
/* read ENV area0 and area1 current using data section address */
ef_port_read(get_env_start_addr(), &area0_cur_using_addr, 4);
ef_port_read(get_env_start_addr() + ENV_AREA_SIZE / 2, &area1_cur_using_addr, 4);
/* if ENV is not initialize or flash has dirty data, set it isn't valid */
if ((area0_cur_using_addr == 0xFFFFFFFF)
|| (area0_cur_using_addr > get_env_start_addr() + ENV_AREA_SIZE / 2)
|| (area0_cur_using_addr < get_env_start_addr() + EF_ERASE_MIN_SIZE))
area0_is_valid = false;
if ((area1_cur_using_addr == 0xFFFFFFFF)
|| (area1_cur_using_addr > get_env_start_addr() + ENV_AREA_SIZE)
|| (area1_cur_using_addr < get_env_start_addr() + ENV_AREA_SIZE / 2 + EF_ERASE_MIN_SIZE))
area1_is_valid = false;
/* check area0 end address when it is valid */
if (area0_is_valid) {
/* read ENV area end address from flash */
ef_port_read(area0_cur_using_addr + ENV_PARAM_PART_INDEX_END_ADDR * 4, &area0_end_addr, 4);
if ((area0_end_addr == 0xFFFFFFFF) || (area0_end_addr < area0_cur_using_addr)
|| (area0_end_addr > area0_cur_using_addr + ENV_USER_SETTING_SIZE))
area0_is_valid = false;
}
/* check area1 end address when it is valid */
if (area1_is_valid) {
/* read ENV area end address from flash */
ef_port_read(area1_cur_using_addr + ENV_PARAM_PART_INDEX_END_ADDR * 4, &area1_end_addr, 4);
if ((area1_end_addr == 0xFFFFFFFF) || (area1_end_addr < area1_cur_using_addr)
|| (area1_end_addr > area1_cur_using_addr + ENV_USER_SETTING_SIZE))
area1_is_valid = false;
}
/* check area0 CRC when it is valid */
if (area0_is_valid) {
/* read ENV area0 crc32 code from flash */
ef_port_read(area0_cur_using_addr + ENV_PARAM_PART_INDEX_DATA_CRC * 4, &area0_crc, 4);
/* read ENV from ENV area0 */
ef_port_read(area0_cur_using_addr, env_cache, area0_end_addr - area0_cur_using_addr);
/* current using data section address is area0 current using data section address */
set_cur_using_data_addr(area0_cur_using_addr);
if (!env_crc_is_ok())
area0_is_valid = false;
}
/* check area1 CRC when it is valid */
if (area1_is_valid) {
/* read ENV area1 crc32 code from flash */
ef_port_read(area1_cur_using_addr + ENV_PARAM_PART_INDEX_DATA_CRC * 4, &area1_crc, 4);
/* read ENV from ENV area1 */
ef_port_read(area1_cur_using_addr, env_cache, area1_end_addr - area1_cur_using_addr);
/* current using data section address is area1 current using data section address */
set_cur_using_data_addr(area1_cur_using_addr);
if (!env_crc_is_ok())
area1_is_valid = false;
}
/* all ENV area CRC is OK then compare saved count */
if (area0_is_valid && area1_is_valid) {
/* read ENV area saved count from flash */
ef_port_read(area0_cur_using_addr + ENV_PARAM_PART_INDEX_SAVED_COUNT * 4,
&area0_saved_count, 4);
ef_port_read(area1_cur_using_addr + ENV_PARAM_PART_INDEX_SAVED_COUNT * 4,
&area1_saved_count, 4);
/* the bigger saved count area is valid */
if ((area0_saved_count > area1_saved_count) || ((area0_saved_count == 0) && (area1_saved_count == 0xFFFFFFFF)))
area1_is_valid = false;
else
area0_is_valid = false;
}
if (area0_is_valid) {
/* current using data section address is area0 current using data section address */
set_cur_using_data_addr(area0_cur_using_addr);
/* next save ENV area address is area1 current using address value */
next_save_area_addr = area1_cur_using_addr;
/* read all ENV from area0 */
ef_port_read(area0_cur_using_addr, env_cache, area0_end_addr - area0_cur_using_addr);
} else if (area1_is_valid) {
/* already read data section and set_cur_using_data_addr above current code,
* so just set next save ENV area address is area0 current using address value */
next_save_area_addr = area0_cur_using_addr;
} else {
/* current using data section address is area1 current using address default value */
set_cur_using_data_addr(area1_default_cur_using_addr);
/* next save ENV area address default is area0 current using address default value */
next_save_area_addr = area0_default_cur_using_addr;
/* save current using data section address to flash*/
if (((result = save_cur_using_data_addr(area0_default_cur_using_addr)) == EF_NO_ERR)
&& ((result = save_cur_using_data_addr(area1_default_cur_using_addr)) == EF_NO_ERR)) {
/* set the ENV to default */
result = ef_env_set_default();
}
}
return result;
}
#endif
/**
* Save ENV to flash.
*/
EfErrCode ef_save_env(void)
{
EfErrCode result = EF_NO_ERR;
uint32_t cur_using_addr_bak, move_offset_addr;
size_t env_used_size = get_env_user_used_size();
uint32_t data_sec_end_addr;
/* ENV ram cache has not changed don't need to save */
if (!env_cache_changed)
return result;
#ifndef EF_ENV_USING_PFS_MODE
data_sec_end_addr = get_env_start_addr() + ENV_AREA_SIZE - 4;
cur_using_addr_bak = get_cur_using_data_addr();
#else
cur_using_addr_bak = next_save_area_addr;
/* replace next_save_area_addr with cur_using_data_addr */
next_save_area_addr = get_cur_using_data_addr();
set_cur_using_data_addr(cur_using_addr_bak);
/* change the ENV detail end address to next save area address */
set_env_detail_end_addr(get_cur_using_data_addr() + env_used_size);
/* area0 or area1 */
if (get_cur_using_data_addr() < get_env_start_addr() + ENV_AREA_SIZE / 2)
data_sec_end_addr = get_env_start_addr() + ENV_AREA_SIZE / 2 - 4;
else
data_sec_end_addr = get_env_start_addr() + ENV_AREA_SIZE - 4;
/* ENV area saved count +1 */
env_cache[ENV_PARAM_PART_INDEX_SAVED_COUNT]++;
#endif
/* wear leveling process, automatic move ENV to next available position */
while (get_cur_using_data_addr() + env_used_size < data_sec_end_addr) {
/* calculate and cache CRC32 code */
env_cache[ENV_PARAM_PART_INDEX_DATA_CRC] = calc_env_crc();
/* erase ENV */
result = ef_port_erase(get_cur_using_data_addr(), env_used_size);
switch (result) {
case EF_NO_ERR: {
EF_INFO("Erased ENV OK.\n");
break;
}
case EF_ERASE_ERR: {
EF_INFO("Warning: Erased ENV fault! Start address is 0x%08X, size is %ld.\n",
get_cur_using_data_addr(), env_used_size);
EF_INFO("Moving ENV to next available position.\n");
/* Calculate move offset address.
* Current strategy is optimistic. It will offset the flash erasure minimum size.
*/
move_offset_addr = EF_ERASE_MIN_SIZE;
/* calculate and set next available data section address */
set_cur_using_data_addr(get_cur_using_data_addr() + move_offset_addr);
/* calculate and set next available ENV detail part end address */
set_env_detail_end_addr(get_env_detail_end_addr() + move_offset_addr);
continue;
}
}
/* write ENV to flash */
result = ef_port_write(get_cur_using_data_addr(), env_cache, env_used_size);
switch (result) {
case EF_NO_ERR: {
EF_INFO("Saved ENV OK.\n");
break;
}
case EF_WRITE_ERR: {
EF_INFO("Warning: Saved ENV fault! Start address is 0x%08X, size is %ld.\n",
get_cur_using_data_addr(), env_used_size);
EF_INFO("Moving ENV to next available position.\n");
/* Calculate move offset address.
* Current strategy is optimistic. It will offset the flash erasure minimum size.
*/
move_offset_addr = EF_ERASE_MIN_SIZE;
/* calculate and set next available data section address */
set_cur_using_data_addr(get_cur_using_data_addr() + move_offset_addr);
/* calculate and set next available ENV detail part end address */
set_env_detail_end_addr(get_env_detail_end_addr() + move_offset_addr);
continue;
}
}
/* save ENV success */
if (result == EF_NO_ERR)
break;
}
if (get_cur_using_data_addr() + env_used_size < data_sec_end_addr) {
/* current using data section address has changed, save it */
if (get_cur_using_data_addr() != cur_using_addr_bak)
result = save_cur_using_data_addr(get_cur_using_data_addr());
} else {
result = EF_ENV_FULL;
EF_INFO("Error: The flash has no available space to save ENV.\n");
}
env_cache_changed = false;
return result;
}
/**
* Calculate the cached ENV CRC32 value.
*
* @return CRC32 value
*/
static uint32_t calc_env_crc(void)
{
uint32_t crc32 = 0;
/* Calculate the ENV end address and all ENV data CRC32.
* The 4 is ENV end address bytes size. */
crc32 = ef_calc_crc32(crc32, &env_cache[ENV_PARAM_PART_INDEX_END_ADDR], 4);
crc32 = ef_calc_crc32(crc32, &env_cache[ENV_PARAM_PART_WORD_SIZE], get_env_detail_size());
EF_DEBUG("Calculate ENV CRC32 number is 0x%08X.\n", crc32);
return crc32;
}
/**
* Check the ENV CRC32
*
* @return true is ok
*/
static bool env_crc_is_ok(void)
{
if (calc_env_crc() == env_cache[ENV_PARAM_PART_INDEX_DATA_CRC]) {
EF_DEBUG("Verify ENV CRC32 result is OK.\n");
return true;
} else
return false;
}
/**
* Save current using data section address to flash.
*
* @param cur_data_addr current using data section address
*
* @return result
*/
#ifndef EF_ENV_USING_PFS_MODE
static EfErrCode save_cur_using_data_addr(uint32_t cur_data_addr)
{
EfErrCode result = EF_NO_ERR;
/* erase ENV system section */
result = ef_port_erase(get_env_start_addr(), 4);
if (result == EF_NO_ERR) {
/* write current using data section address to flash */
result = ef_port_write(get_env_start_addr(), &cur_data_addr, 4);
if (result == EF_WRITE_ERR) {
EF_INFO("Error: Write system section fault! Start address is 0x%08X, size is %ld.\n",
get_env_start_addr(), 4);
EF_INFO("Note: The ENV can not be used.\n");
}
} else {
EF_INFO("Error: Erased system section fault! Start address is 0x%08X, size is %ld.\n",
get_env_start_addr(), 4);
EF_INFO("Note: The ENV can not be used\n");
}
return result;
}
#else
static EfErrCode save_cur_using_data_addr(uint32_t cur_data_addr)
{
EfErrCode result = EF_NO_ERR;
uint32_t cur_system_sec_addr;
if (cur_data_addr < get_env_start_addr() + ENV_AREA_SIZE / 2) {
/* current using system section is in ENV area0 */
cur_system_sec_addr = get_env_start_addr();
} else {
/* current using system section is in ENV area1 */
cur_system_sec_addr = get_env_start_addr() + ENV_AREA_SIZE / 2;
}
/* erase ENV system section */
result = ef_port_erase(cur_system_sec_addr, 4);
if (result == EF_NO_ERR) {
/* write area0 and area1 current using data section address to flash */
result = ef_port_write(cur_system_sec_addr, &cur_data_addr, 4);
if (result == EF_WRITE_ERR) {
EF_INFO("Error: Write system section fault! Start address is 0x%08X, size is %ld.\n",
cur_system_sec_addr, 4);
EF_INFO("Note: The ENV can not be used.\n");
}
} else {
EF_INFO("Error: Erased system section fault! Start address is 0x%08X, size is %ld.\n",
cur_system_sec_addr, 4);
EF_INFO("Note: The ENV can not be used\n");
}
return result;
}
#endif
/**
* Set and save an ENV. If set ENV is success then will save it.
*
* @param key ENV name
* @param value ENV value
*
* @return result
*/
EfErrCode ef_set_and_save_env(const char *key, const char *value)
{
EfErrCode result = EF_NO_ERR;
result = ef_set_env(key, value);
if (result == EF_NO_ERR)
result = ef_save_env();
return result;
}
#endif /* EF_ENV_USING_WL_MODE */
#endif /* EF_USING_ENV */
@@ -0,0 +1,294 @@
/*
* Copyright (c) 2015-2017, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: IAP(In-Application Programming) operating interface.
* Created on: 2015-01-05
*/
#include <easyflash.h>
#ifdef EF_USING_IAP
/* IAP section backup application section start address in flash */
static uint32_t bak_app_start_addr = 0;
/**
* Flash IAP function initialize.
*
* @return result
*/
EfErrCode ef_iap_init(void)
{
EfErrCode result = EF_NO_ERR;
bak_app_start_addr = EF_START_ADDR ;
#if defined(EF_USING_ENV)
bak_app_start_addr += ENV_AREA_SIZE;
#endif
#if defined(EF_USING_LOG)
bak_app_start_addr += LOG_AREA_SIZE;
#endif
return result;
}
/**
* Erase backup area application data.
*
* @param app_size application size
*
* @return result
*/
EfErrCode ef_erase_bak_app(size_t app_size)
{
EfErrCode result = EF_NO_ERR;
result = ef_port_erase(ef_get_bak_app_start_addr(), app_size);
switch (result) {
case EF_NO_ERR: {
EF_INFO("Erased backup area application OK.\n");
break;
}
case EF_ERASE_ERR: {
EF_INFO("Warning: Erase backup area application fault!\n");
/* will return when erase fault */
return result;
}
}
return result;
}
/**
* Erase user old application by using specified erase function.
*
* @param user_app_addr application entry address
* @param app_size application size
* @param app_erase user specified application erase function
*
* @return result
*/
EfErrCode ef_erase_spec_user_app(uint32_t user_app_addr, size_t app_size,
EfErrCode(*app_erase)(uint32_t addr, size_t size))
{
EfErrCode result = EF_NO_ERR;
result = app_erase(user_app_addr, app_size);
switch (result) {
case EF_NO_ERR: {
EF_INFO("Erased user application OK.\n");
break;
}
case EF_ERASE_ERR: {
EF_INFO("Warning: Erase user application fault!\n");
/* will return when erase fault */
return result;
}
}
return result;
}
/**
* Erase user old application by using default `ef_port_erase` function.
*
* @param user_app_addr application entry address
* @param app_size application size
*
* @return result
*/
EfErrCode ef_erase_user_app(uint32_t user_app_addr, size_t app_size)
{
return ef_erase_spec_user_app(user_app_addr, app_size, ef_port_erase);
}
/**
* Erase old bootloader
*
* @param bl_addr bootloader entry address
* @param bl_size bootloader size
*
* @return result
*/
EfErrCode ef_erase_bl(uint32_t bl_addr, size_t bl_size)
{
EfErrCode result = EF_NO_ERR;
result = ef_port_erase(bl_addr, bl_size);
switch (result) {
case EF_NO_ERR: {
EF_INFO("Erased bootloader OK.\n");
break;
}
case EF_ERASE_ERR: {
EF_INFO("Warning: Erase bootloader fault!\n");
/* will return when erase fault */
return result;
}
}
return result;
}
/**
* Write data of application to backup area.
*
* @param data a part of application
* @param size data size
* @param cur_size current write application size
* @param total_size application total size
*
* @return result
*/
EfErrCode ef_write_data_to_bak(uint8_t *data, size_t size, size_t *cur_size,
size_t total_size)
{
EfErrCode result = EF_NO_ERR;
/* make sure don't write excess data */
if (*cur_size + size > total_size)
size = total_size - *cur_size;
result = ef_port_write(ef_get_bak_app_start_addr() + *cur_size, (uint32_t *) data, size);
switch (result) {
case EF_NO_ERR: {
*cur_size += size;
EF_DEBUG("Write data to backup area OK.\n");
break;
}
case EF_WRITE_ERR: {
EF_INFO("Warning: Write data to backup area fault!\n");
break;
}
}
return result;
}
/**
* Copy backup area application to application entry by using specified write function.
*
* @param user_app_addr application entry address
* @param app_size application size
* @param app_write user specified application write function
*
* @return result
*/
EfErrCode ef_copy_spec_app_from_bak(uint32_t user_app_addr, size_t app_size,
EfErrCode(*app_write)(uint32_t addr, const uint32_t *buf, size_t size))
{
size_t cur_size;
uint32_t app_cur_addr, bak_cur_addr;
EfErrCode result = EF_NO_ERR;
/* 32 words size buffer */
uint32_t buff[32];
/* cycle copy data */
for (cur_size = 0; cur_size < app_size; cur_size += sizeof(buff)) {
app_cur_addr = user_app_addr + cur_size;
bak_cur_addr = ef_get_bak_app_start_addr() + cur_size;
ef_port_read(bak_cur_addr, buff, sizeof(buff));
result = app_write(app_cur_addr, buff, sizeof(buff));
if (result != EF_NO_ERR)
break;
}
switch (result) {
case EF_NO_ERR: {
EF_INFO("Write data to application entry OK.\n");
break;
}
case EF_WRITE_ERR: {
EF_INFO("Warning: Write data to application entry fault!\n");
break;
}
}
return result;
}
/**
* Copy backup area application to application entry by using default `ef_port_write` function.
*
* @param user_app_addr application entry address
* @param app_size application size
*
* @return result
*/
EfErrCode ef_copy_app_from_bak(uint32_t user_app_addr, size_t app_size)
{
return ef_copy_spec_app_from_bak(user_app_addr, app_size, ef_port_write);
}
/**
* Copy backup area bootloader to bootloader entry.
*
* @param bl_addr bootloader entry address
* @param bl_size bootloader size
*
* @return result
*/
EfErrCode ef_copy_bl_from_bak(uint32_t bl_addr, size_t bl_size)
{
size_t cur_size;
uint32_t bl_cur_addr, bak_cur_addr;
EfErrCode result = EF_NO_ERR;
/* 32 words buffer */
uint32_t buff[32];
/* cycle copy data by 32bytes buffer */
for (cur_size = 0; cur_size < bl_size; cur_size += sizeof(buff)) {
bl_cur_addr = bl_addr + cur_size;
bak_cur_addr = ef_get_bak_app_start_addr() + cur_size;
ef_port_read(bak_cur_addr, buff, sizeof(buff));
result = ef_port_write(bl_cur_addr, buff, sizeof(buff));
if (result != EF_NO_ERR)
break;
}
switch (result) {
case EF_NO_ERR: {
EF_INFO("Write data to bootloader entry OK.\n");
break;
}
case EF_WRITE_ERR: {
EF_INFO("Warning: Write data to bootloader entry fault!\n");
break;
}
}
return result;
}
/**
* Get IAP section start address in flash.
*
* @return size
*/
uint32_t ef_get_bak_app_start_addr(void)
{
return bak_app_start_addr;
}
#endif /* EF_USING_IAP */
@@ -0,0 +1,698 @@
/*
* Copyright (c) 2015-2017, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: Save logs to flash.
* Created on: 2015-06-04
*/
#include <easyflash.h>
#ifdef EF_USING_LOG
/* magic code on every sector header. 'EF' is 0x4546 */
#define LOG_SECTOR_MAGIC 0x4546
/* sector header size, include the sector magic code and status magic code */
#define LOG_SECTOR_HEADER_SIZE 4
/**
* Sector status magic code
* The sector status is 16-Bits after LOG_SECTOR_MAGIC at every sector header.
* =======================
* | header(4B) | status |
* -----------------------
* | 0x4546FFFF | empty |
* | 0x4546FFFE | using |
* | 0x4546FFFC | full |
* =======================
*
* State transition relationship: empty->using->full
* The FULL status will change to EMPTY after sector clean.
*/
enum {
SECTOR_STATUS_MAGIC_EMPUT = 0xFFFF,
SECTOR_STATUS_MAGIC_USING = 0xFFFE,
SECTOR_STATUS_MAGIC_FULL = 0xFFFC,
};
typedef enum {
SECTOR_STATUS_EMPUT,
SECTOR_STATUS_USING,
SECTOR_STATUS_FULL,
SECTOR_STATUS_HEADER_ERROR,
} SectorStatus;
/* the stored logs start address and end address. It's like a ring buffer which implement by flash. */
static uint32_t log_start_addr = 0, log_end_addr = 0;
/* saved log area address for flash */
static uint32_t log_area_start_addr = 0;
/* initialize OK flag */
static bool init_ok = false;
static void find_start_and_end_addr(void);
static uint32_t get_next_flash_sec_addr(uint32_t cur_addr);
/**
* The flash save log function initialize.
*
* @return result
*/
EfErrCode ef_log_init(void)
{
EfErrCode result = EF_NO_ERR;
EF_ASSERT(LOG_AREA_SIZE);
EF_ASSERT(EF_ERASE_MIN_SIZE);
/* the log area size must be an integral multiple of erase minimum size. */
EF_ASSERT(LOG_AREA_SIZE % EF_ERASE_MIN_SIZE == 0);
/* the log area size must be more than twice of EF_ERASE_MIN_SIZE */
EF_ASSERT(LOG_AREA_SIZE / EF_ERASE_MIN_SIZE >= 2);
#ifdef EF_USING_ENV
log_area_start_addr = EF_START_ADDR + ENV_AREA_SIZE;
#else
log_area_start_addr = EF_START_ADDR;
#endif
/* find the log store start address and end address */
find_start_and_end_addr();
/* initialize OK */
init_ok = true;
return result;
}
/**
* Get flash sector current status.
*
* @param addr sector address, this function will auto calculate the sector header address by this address.
*
* @return the flash sector current status
*/
static SectorStatus get_sector_status(uint32_t addr)
{
uint32_t header = 0, header_addr = 0;
uint16_t sector_magic = 0, status_magic = 0;
/* calculate the sector header address */
header_addr = addr / EF_ERASE_MIN_SIZE * EF_ERASE_MIN_SIZE;
if (ef_port_read(header_addr, &header, sizeof(header)) == EF_NO_ERR) {
sector_magic = header >> 16;
status_magic = header;
} else {
EF_DEBUG("Error: Read sector header data error.\n");
return SECTOR_STATUS_HEADER_ERROR;
}
/* compare header magic code */
if (sector_magic == LOG_SECTOR_MAGIC) {
switch (status_magic) {
case SECTOR_STATUS_MAGIC_EMPUT:
return SECTOR_STATUS_EMPUT;
case SECTOR_STATUS_MAGIC_USING:
return SECTOR_STATUS_USING;
case SECTOR_STATUS_MAGIC_FULL:
return SECTOR_STATUS_FULL;
default:
return SECTOR_STATUS_HEADER_ERROR;
}
} else
return SECTOR_STATUS_HEADER_ERROR;
}
/**
* Write flash sector current status.
*
* @param addr sector address, this function will auto calculate the sector header address by this address.
* @param status sector cur status
*
* @return result
*/
static EfErrCode write_sector_status(uint32_t addr, SectorStatus status)
{
uint32_t header = 0, header_addr = 0;
uint16_t status_magic;
/* calculate the sector header address */
header_addr = addr / EF_ERASE_MIN_SIZE * EF_ERASE_MIN_SIZE;
switch (status) {
case SECTOR_STATUS_EMPUT: {
status_magic = SECTOR_STATUS_MAGIC_EMPUT;
break;
}
case SECTOR_STATUS_USING: {
status_magic = SECTOR_STATUS_MAGIC_USING;
break;
}
case SECTOR_STATUS_FULL: {
status_magic = SECTOR_STATUS_MAGIC_FULL;
break;
}
}
header = (LOG_SECTOR_MAGIC << 16) | status_magic;
return ef_port_write(header_addr, &header, sizeof(header));
}
/**
* Find the current flash sector using end address by continuous 0xFF.
*
* @param addr sector address
*
* @return current flash sector using end address
*/
static uint32_t find_sec_using_end_addr(uint32_t addr)
{
/* read section data buffer size */
#define READ_BUF_SIZE 32
uint32_t sector_start = addr, data_start = addr, continue_ff = 0, read_buf_size = 0, i;
uint8_t buf[READ_BUF_SIZE];
EF_ASSERT(READ_BUF_SIZE % 4 == 0);
/* calculate the sector start and data start address */
sector_start = addr / EF_ERASE_MIN_SIZE * EF_ERASE_MIN_SIZE;
data_start = sector_start + LOG_SECTOR_HEADER_SIZE;
/* counts continuous 0xFF which is end of sector */
while (data_start < sector_start + EF_ERASE_MIN_SIZE) {
if (data_start + READ_BUF_SIZE < sector_start + EF_ERASE_MIN_SIZE)
read_buf_size = READ_BUF_SIZE;
else
read_buf_size = sector_start + EF_ERASE_MIN_SIZE - data_start;
ef_port_read(data_start, (uint32_t *)buf, read_buf_size);
for (i = 0; i < read_buf_size; i++) {
if (buf[i] == 0xFF)
continue_ff++;
else
continue_ff = 0;
}
data_start += read_buf_size;
}
/* calculate current flash sector using end address */
if (continue_ff >= EF_ERASE_MIN_SIZE - LOG_SECTOR_HEADER_SIZE) {
/* from 0 to sec_size all sector is 0xFF, so the sector is empty */
return sector_start + LOG_SECTOR_HEADER_SIZE;
} else if (continue_ff >= 4) {
/* form end_addr - 4 to sec_size length all area is 0xFF, so it's used part of the sector.
* the address must be word alignment. */
if (continue_ff % 4 != 0)
continue_ff = (continue_ff / 4 + 1) * 4;
return sector_start + EF_ERASE_MIN_SIZE - continue_ff;
} else {
/* all sector not has continuous 0xFF, so the sector is full */
return sector_start + EF_ERASE_MIN_SIZE;
}
}
/**
* Find the log store start address and end address.
* It's like a ring buffer which implement by flash.
* The flash log area has two state when find start address and end address.
* state 1 state 2
* |============| |============|
* log area start--> |############| <-- start address |############| <-- end address
* |############| | empty |
* |------------| |------------|
* |############| |############| <-- start address
* |############| |############|
* |------------| |------------|
* | . | | . |
* | . | | . |
* | . | | . |
* |------------| |------------|
* |############| <-- end address |############|
* | empty | |############|
* log area end --> |============| |============|
*
* LOG_AREA_SIZE = log area end - log area star
*
*/
static void find_start_and_end_addr(void)
{
size_t cur_size = 0;
SectorStatus cur_sec_status, last_sec_status;
uint32_t cur_using_sec_addr = 0;
/* all status sector counts */
size_t empty_sec_counts = 0, using_sec_counts = 0, full_sector_counts = 0;
/* total sector number */
size_t total_sec_num = LOG_AREA_SIZE / EF_ERASE_MIN_SIZE;
/* see comment of find_start_and_end_addr function */
uint8_t cur_log_sec_state = 0;
/* get the first sector status */
cur_sec_status = get_sector_status(log_area_start_addr);
last_sec_status = cur_sec_status;
for (cur_size = EF_ERASE_MIN_SIZE; cur_size < LOG_AREA_SIZE; cur_size += EF_ERASE_MIN_SIZE) {
/* get current sector status */
cur_sec_status = get_sector_status(log_area_start_addr + cur_size);
/* compare last and current status */
switch (last_sec_status) {
case SECTOR_STATUS_EMPUT: {
switch (cur_sec_status) {
case SECTOR_STATUS_EMPUT:
break;
case SECTOR_STATUS_USING:
EF_DEBUG("Error: Log area error! Now will clean all log area.\n");
ef_log_clean();
return;
case SECTOR_STATUS_FULL:
EF_DEBUG("Error: Log area error! Now will clean all log area.\n");
ef_log_clean();
return;
}
empty_sec_counts++;
break;
}
case SECTOR_STATUS_USING: {
switch (cur_sec_status) {
case SECTOR_STATUS_EMPUT:
/* like state 1 */
cur_log_sec_state = 1;
log_start_addr = log_area_start_addr;
cur_using_sec_addr = log_area_start_addr + cur_size - EF_ERASE_MIN_SIZE;
break;
case SECTOR_STATUS_USING:
EF_DEBUG("Error: Log area error! Now will clean all log area.\n");
ef_log_clean();
return;
case SECTOR_STATUS_FULL:
/* like state 2 */
cur_log_sec_state = 2;
log_start_addr = log_area_start_addr + cur_size;
cur_using_sec_addr = log_area_start_addr + cur_size - EF_ERASE_MIN_SIZE;
break;
}
using_sec_counts++;
break;
}
case SECTOR_STATUS_FULL: {
switch (cur_sec_status) {
case SECTOR_STATUS_EMPUT:
/* like state 1 */
if (cur_log_sec_state == 2) {
EF_DEBUG("Error: Log area error! Now will clean all log area.\n");
ef_log_clean();
return;
} else {
cur_log_sec_state = 1;
log_start_addr = log_area_start_addr;
log_end_addr = log_area_start_addr + cur_size;
cur_using_sec_addr = log_area_start_addr + cur_size - EF_ERASE_MIN_SIZE;
}
break;
case SECTOR_STATUS_USING:
if (total_sec_num <= 2) {
/* like state 1 */
cur_log_sec_state = 1;
log_start_addr = log_area_start_addr;
cur_using_sec_addr = log_area_start_addr + cur_size;
} else {
/* like state 2 when the sector is the last one */
if (cur_size + EF_ERASE_MIN_SIZE >= LOG_AREA_SIZE) {
cur_log_sec_state = 2;
log_start_addr = log_area_start_addr + cur_size;
cur_using_sec_addr = log_area_start_addr + cur_size - EF_ERASE_MIN_SIZE;
}
}
break;
case SECTOR_STATUS_FULL:
break;
}
full_sector_counts++;
break;
}
case SECTOR_STATUS_HEADER_ERROR:
EF_DEBUG("Error: Log sector header error! Now will clean all log area.\n");
ef_log_clean();
return;
}
last_sec_status = cur_sec_status;
}
/* the last sector status counts */
if (cur_sec_status == SECTOR_STATUS_EMPUT)
empty_sec_counts++;
else if (cur_sec_status == SECTOR_STATUS_USING)
using_sec_counts++;
else if (cur_sec_status == SECTOR_STATUS_FULL)
full_sector_counts++;
else if (cur_sec_status == SECTOR_STATUS_HEADER_ERROR) {
EF_DEBUG("Error: Log sector header error! Now will clean all log area.\n");
ef_log_clean();
return;
}
if (using_sec_counts != 1) {
/* this state is almost impossible */
EF_DEBUG("Error: There must be only one sector status is USING! Now will clean all log area.\n");
ef_log_clean();
} else {
/* find the end address */
log_end_addr = find_sec_using_end_addr(cur_using_sec_addr);
}
}
/**
* Get log used flash total size.
*
* @return log used flash total size. @note NOT contain sector headers
*/
size_t ef_log_get_used_size(void)
{
size_t header_total_num = 0, physical_size = 0;
/* must be call this function after initialize OK */
if (!init_ok)
return 0;
if (log_start_addr < log_end_addr)
physical_size = log_end_addr - log_start_addr;
else
physical_size = LOG_AREA_SIZE - (log_start_addr - log_end_addr);
header_total_num = physical_size / EF_ERASE_MIN_SIZE + 1;
return physical_size - header_total_num * LOG_SECTOR_HEADER_SIZE;
}
/**
* Sequential reading log data. It will ignore sector headers.
*
* @param addr address
* @param log log buffer
* @param size log size, not contain sector headers.
*
* @return result
*/
static EfErrCode log_seq_read(uint32_t addr, uint32_t *log, size_t size)
{
EfErrCode result = EF_NO_ERR;
size_t read_size = 0, read_size_temp = 0;
while (size) {
/* move to sector data address */
if ((addr + read_size) % EF_ERASE_MIN_SIZE == 0)
addr += LOG_SECTOR_HEADER_SIZE;
/* calculate current sector last data size */
read_size_temp = EF_ERASE_MIN_SIZE - (addr % EF_ERASE_MIN_SIZE);
if (size < read_size_temp)
read_size_temp = size;
result = ef_port_read(addr + read_size, log + read_size / 4, read_size_temp);
if (result != EF_NO_ERR)
return result;
read_size += read_size_temp;
size -= read_size_temp;
}
return result;
}
/**
* Calculate flash physical address by log index.
*
* @param index log index
*
* @return flash physical address
*/
static uint32_t log_index2addr(size_t index)
{
size_t header_total_offset = 0;
/* total include sector number */
size_t sector_num = index / (EF_ERASE_MIN_SIZE - LOG_SECTOR_HEADER_SIZE) + 1;
header_total_offset = sector_num * LOG_SECTOR_HEADER_SIZE;
if (log_start_addr < log_end_addr)
return log_start_addr + index + header_total_offset;
else {
if (log_start_addr + index + header_total_offset < log_area_start_addr + LOG_AREA_SIZE)
return log_start_addr + index + header_total_offset;
else
return log_start_addr + index + header_total_offset - LOG_AREA_SIZE;
}
}
/**
* Read log from flash.
*
* @param index index for saved log.
* Minimum index is 0.
* Maximum index is ef_log_get_used_size() - 1.
* @param log the log which will read from flash
* @param size read bytes size
*
* @return result
*/
EfErrCode ef_log_read(size_t index, uint32_t *log, size_t size)
{
EfErrCode result = EF_NO_ERR;
size_t cur_using_size = ef_log_get_used_size();
size_t read_size_temp = 0;
size_t header_total_num = 0;
if (!size)
return result;
EF_ASSERT(size % 4 == 0);
EF_ASSERT(index < cur_using_size);
if (index + size > cur_using_size) {
EF_DEBUG("Warning: Log read size out of bound. Cut read size.\n");
size = cur_using_size - index;
}
/* must be call this function after initialize OK */
if (!init_ok)
return EF_ENV_INIT_FAILED;
if (log_start_addr < log_end_addr)
log_seq_read(log_index2addr(index), log, size);
else {
if (log_index2addr(index) + size <= log_area_start_addr + LOG_AREA_SIZE) {
/* Flash log area
* |--------------|
* log_area_start_addr --> |##############|
* |##############|
* |##############|
* |--------------|
* |##############|
* |##############|
* |##############| <-- log_end_addr
* |--------------|
* log_start_addr --> |##############|
* read start --> |**************| <-- read end
* |##############|
* |--------------|
*
* read from (log_start_addr + log_index2addr(index)) to (log_start_addr + index + log_index2addr(index))
*/
result = log_seq_read(log_index2addr(index), log, size);
} else if (log_index2addr(index) < log_area_start_addr + LOG_AREA_SIZE) {
/* Flash log area
* |--------------|
* log_area_start_addr --> |**************| <-- read end
* |##############|
* |##############|
* |--------------|
* |##############|
* |##############|
* |##############| <-- log_end_addr
* |--------------|
* log_start_addr --> |##############|
* read start --> |**************|
* |**************|
* |--------------|
* read will by 2 steps
* step1: read from (log_start_addr + log_index2addr(index)) to flash log area end address
* step2: read from flash log area start address to read size's end address
*/
read_size_temp = (log_area_start_addr + LOG_AREA_SIZE) - log_index2addr(index);
header_total_num = read_size_temp / EF_ERASE_MIN_SIZE;
/* Minus some ignored bytes */
read_size_temp -= header_total_num * LOG_SECTOR_HEADER_SIZE;
result = log_seq_read(log_index2addr(index), log, read_size_temp);
if (result == EF_NO_ERR)
result = log_seq_read(log_area_start_addr, log + read_size_temp / 4, size - read_size_temp);
} else {
/* Flash log area
* |--------------|
* log_area_start_addr --> |##############|
* read start --> |**************|
* |**************| <-- read end
* |--------------|
* |##############|
* |##############|
* |##############| <-- log_end_addr
* |--------------|
* log_start_addr --> |##############|
* |##############|
* |##############|
* |--------------|
* read from (log_start_addr + log_index2addr(index) - LOG_AREA_SIZE) to read size's end address
*/
result = log_seq_read(log_index2addr(index) - LOG_AREA_SIZE, log, size);
}
}
return result;
}
/**
* Write log to flash.
*
* @param log the log which will be write to flash
* @param size write bytes size
*
* @return result
*/
EfErrCode ef_log_write(const uint32_t *log, size_t size)
{
EfErrCode result = EF_NO_ERR;
size_t write_size = 0, writable_size = 0;
uint32_t write_addr = log_end_addr, erase_addr;
SectorStatus sector_status;
EF_ASSERT(size % 4 == 0);
/* must be call this function after initialize OK */
if (!init_ok)
return EF_ENV_INIT_FAILED;
if ((sector_status = get_sector_status(write_addr)) == SECTOR_STATUS_HEADER_ERROR)
return EF_WRITE_ERR;
/* write some log when current sector status is USING and EMPTY */
if ((sector_status == SECTOR_STATUS_USING) || (sector_status == SECTOR_STATUS_EMPUT)) {
/* write the already erased but not used area */
writable_size = EF_ERASE_MIN_SIZE - ((write_addr - log_area_start_addr) % EF_ERASE_MIN_SIZE);
if (size >= writable_size) {
result = ef_port_write(write_addr, log, writable_size);
if (result != EF_NO_ERR)
goto exit;
/* change the current sector status to FULL */
result = write_sector_status(write_addr, SECTOR_STATUS_FULL);
if (result != EF_NO_ERR)
goto exit;
write_size += writable_size;
} else {
result = ef_port_write(write_addr, log, size);
log_end_addr = write_addr + size;
goto exit;
}
}
/* erase and write remain log */
while (true) {
/* calculate next available sector address */
erase_addr = write_addr = get_next_flash_sec_addr(write_addr - 4);
/* move the flash log start address to next available sector address */
if (log_start_addr == erase_addr)
log_start_addr = get_next_flash_sec_addr(log_start_addr);
/* erase sector */
result = ef_port_erase(erase_addr, EF_ERASE_MIN_SIZE);
if (result != EF_NO_ERR)
goto exit;
/* change the sector status to USING when write begin sector start address */
result = write_sector_status(write_addr, SECTOR_STATUS_USING);
if (result == EF_NO_ERR)
write_addr += LOG_SECTOR_HEADER_SIZE;
else
goto exit;
/* calculate current sector writable data size */
writable_size = EF_ERASE_MIN_SIZE - LOG_SECTOR_HEADER_SIZE;
if (size - write_size >= writable_size) {
result = ef_port_write(write_addr, log + write_size / 4, writable_size);
if (result != EF_NO_ERR)
goto exit;
/* change the current sector status to FULL */
result = write_sector_status(write_addr, SECTOR_STATUS_FULL);
if (result != EF_NO_ERR)
goto exit;
log_end_addr = write_addr + writable_size;
write_size += writable_size;
write_addr += writable_size;
} else {
result = ef_port_write(write_addr, log + write_size / 4, size - write_size);
if (result != EF_NO_ERR)
goto exit;
log_end_addr = write_addr + (size - write_size);
break;
}
}
exit:
return result;
}
/**
* Get next flash sector address.The log total sector like ring buffer which implement by flash.
*
* @param cur_addr cur flash address
*
* @return next flash sector address
*/
static uint32_t get_next_flash_sec_addr(uint32_t cur_addr)
{
size_t cur_sec_id = (cur_addr - log_area_start_addr) / EF_ERASE_MIN_SIZE;
size_t sec_total_num = LOG_AREA_SIZE / EF_ERASE_MIN_SIZE;
if (cur_sec_id + 1 >= sec_total_num) {
/* return to ring head */
return log_area_start_addr;
} else
return log_area_start_addr + (cur_sec_id + 1) * EF_ERASE_MIN_SIZE;
}
/**
* Clean all log which in flash.
*
* @return result
*/
EfErrCode ef_log_clean(void)
{
EfErrCode result = EF_NO_ERR;
uint32_t write_addr = log_area_start_addr;
/* clean address */
log_start_addr = log_area_start_addr;
log_end_addr = log_start_addr + LOG_SECTOR_HEADER_SIZE;
/* erase log flash area */
result = ef_port_erase(log_area_start_addr, LOG_AREA_SIZE);
if (result != EF_NO_ERR)
goto exit;
/* setting first sector is USING */
write_sector_status(write_addr, SECTOR_STATUS_USING);
if (result != EF_NO_ERR)
goto exit;
write_addr += EF_ERASE_MIN_SIZE;
/* add sector header */
while (true) {
write_sector_status(write_addr, SECTOR_STATUS_EMPUT);
if (result != EF_NO_ERR)
goto exit;
write_addr += EF_ERASE_MIN_SIZE;
if (write_addr >= log_area_start_addr + LOG_AREA_SIZE)
break;
}
exit:
return result;
}
#endif /* EF_USING_LOG */
@@ -0,0 +1,95 @@
/*
* Copyright (c) 2015-2017, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: Some utils for this library.
* Created on: 2015-01-14
*/
#include <easyflash.h>
static const uint32_t crc32_table[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
/**
* Calculate the CRC32 value of a memory buffer.
*
* @param crc accumulated CRC32 value, must be 0 on first call
* @param buf buffer to calculate CRC32 value for
* @param size bytes in buffer
*
* @return calculated CRC32 value
*/
uint32_t ef_calc_crc32(uint32_t crc, const void *buf, size_t size)
{
const uint8_t *p;
p = (const uint8_t *)buf;
crc = crc ^ ~0U;
while (size--)
crc = crc32_table[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
return crc ^ ~0U;
}
@@ -0,0 +1,167 @@
/*
* Copyright (C) 2022 Beken Corporation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "key_handle.h"
#include <common/bk_kernel_err.h>
#include <common/bk_include.h>
#include <common/bk_typedef.h>
#include "bk_arm_arch.h"
#include "bk_gpio.h"
#include "bk_uart.h"
#include "bk_music_msg.h"
#if(CONFIG_MP3PLAYER == 1)
#define SD_DEBOUNCE_COUNT 50
#define KEY_SCAN_INTERVAL_10MS 10
#if (CONFIG_SOC_BK7251)
#define SD_CARD_DETECT_PIN 31
#else
#define SD_CARD_DETECT_PIN 25
#endif
#define KEY_PLAY_PAUSE_PIN 28
#define SD_CARD_OFFLINE 0
#define SD_CARD_ONLINE 1
#define KEY_SHORTUP_COUNTER 3 //30ms
#define KEY_LONG_COUNTER 80 //800ms
#define KEY_LONGUP_COUNTER 84 //840ms
#define KEY_HOLD_COUNTER 110 //1100ms
static void key_scan_callback(void *arg);
extern void bmsg_music_sender(void *arg);
static UINT16 backup_keyval = MSG_NO_KEY;
static UINT16 keycount = 0;
static UINT16 sd_online = SD_CARD_OFFLINE;
static UINT16 detect_cnt = 0;
static beken_timer_t key_handle_timer = {0};
void key_init(void)
{
UINT32 param;
bk_err_t err;
param = GPIO_CFG_PARAM(SD_CARD_DETECT_PIN, GMODE_INPUT_PULLUP);
sddev_control(DD_DEV_TYPE_GPIO, CMD_GPIO_CFG, &param);
param = GPIO_CFG_PARAM(KEY_PLAY_PAUSE_PIN, GMODE_INPUT_PULLUP);
sddev_control(DD_DEV_TYPE_GPIO, CMD_GPIO_CFG, &param);
err = rtos_init_timer(&key_handle_timer,
KEY_SCAN_INTERVAL_10MS,
key_scan_callback,
(void *)0);
BK_ASSERT(kNoErr == err);
err = rtos_start_timer(&key_handle_timer);
BK_ASSERT(kNoErr == err);
KEY_PRT("==key init==\r\n");
}
uint8 sd_is_attached(void)
{
return (sd_online);
}
static void sd_detect_handle()
{
UINT32 sd_pin_level;
UINT32 sd_detect_pin = SD_CARD_DETECT_PIN;
sd_pin_level = sddev_control(DD_DEV_TYPE_GPIO, CMD_GPIO_INPUT, &sd_detect_pin);
UINT32 msg;
if (sd_pin_level) {
if (sd_online == SD_CARD_ONLINE) {
detect_cnt = 0;
sd_online = SD_CARD_OFFLINE;
msg = MSG_SD_DETACH;
//?detach???
bmsg_music_sender((void *)msg);
}
} else {
if (sd_online == SD_CARD_OFFLINE) {
if (detect_cnt < SD_DEBOUNCE_COUNT)
detect_cnt++;
else {
sd_online = SD_CARD_ONLINE;
msg = MSG_SD_ATTACH;
//?attach???
bmsg_music_sender((void *)msg);
}
}
}
}
static UINT16 keyIOdetect(void)
{
UINT16 key_pin_level;
UINT16 keyValue = MSG_NO_KEY;;
UINT32 key_detect_pin = KEY_PLAY_PAUSE_PIN;
key_pin_level = sddev_control(DD_DEV_TYPE_GPIO, CMD_GPIO_INPUT, &key_detect_pin);
if (key_pin_level == 0)
keyValue = MSG_KEY_PLAY;
return keyValue;
}
static void key_detect_handle(void)
{
UINT32 msg;
UINT16 keyval = keyIOdetect();
if (keyval == MSG_NO_KEY) {
if (keycount >= KEY_SHORTUP_COUNTER) {
if (keycount > KEY_LONG_COUNTER)
msg = KEY_LONG_UP | backup_keyval;
else
msg = backup_keyval;
bmsg_music_sender((void *)msg);
}
keycount = 0;
backup_keyval = MSG_NO_KEY;
} else {
if (keyval != backup_keyval) {
keycount = 0;
backup_keyval = keyval;
}
keycount++;
if ((keycount == KEY_LONG_COUNTER) || (keycount == KEY_HOLD_COUNTER)) {
if (keycount == KEY_LONG_COUNTER)
msg = KEY_LONG | keyval;
else {
keycount = KEY_LONGUP_COUNTER;
msg = KEY_HOLD | keyval;
}
bmsg_music_sender((void *)msg);
}
}
}
static void key_scan_callback(void *arg)
{
sd_detect_handle();
key_detect_handle();
}
#endif
+35
View File
@@ -0,0 +1,35 @@
# Copyright (C) 2022 Beken Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT 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")
import("${beken_sdk_dir}/sdkconfig.gni")
import("${board_adapter_dir}/hals/sdk_dir.gni")
module_name = get_path_info(rebase_path("."), "name")
static_library(module_name) {
sources = [
"app/media_app.c",
"cli/media_cli.c",
"comm/comm_act.c",
"comm/frame_buffer.c",
"core/media_major.c",
]
public_configs = [
":public",
"${beken_sdk_dir}/components/bk_wifi:public",
"${beken_sdk_dir}/components/bk_cli:public",
]
}
config("public") {
include_dirs = [ "include" ]
}
@@ -8,7 +8,7 @@ if (NOT CONFIG_SLAVE_CORE)
comm/comm_act.c
comm/frame_buffer.c
app/media_app.c
utils/mlist.c
#utils/mlist.c
)
if (CONFIG_CAMERA OR CONFIG_USB_UVC)
@@ -1,224 +0,0 @@
// Copyright (C) 2022 Beken Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <os/os.h>
#include <components/log.h>
#include "media_core.h"
#include "aud_act.h"
#include <os/os.h>
#include <os/mem.h>
#include <os/str.h>
#include <driver/aud.h>
#include <driver/aud_types.h>
#include <driver/dma.h>
#include "aud_hal.h"
#include "sys_driver.h"
#include "aud_driver.h"
#include <driver/psram.h>
#include <modules/aec.h>
#include <modules/audio_ring_buff.h>
#include <modules/g711.h>
#include "gpio_driver.h"
#include <driver/gpio.h>
#include <soc/mapping.h>
#include "adc_ccb.h"
#define TAG "adc_ccb"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
#define AUD_8K_FRAME_SAMP_SIZE 160*2
dma_id_t aud_adc_dma_id = DMA_ID_MAX;
static bk_err_t audio_adc_config()
{
bk_err_t ret = BK_OK;
aud_adc_config_t adc_config;
adc_config.mic_config = AUD_MIC_MIC1_ENABLE;
adc_config.samp_rate = AUD_ADC_SAMP_RATE_8K;
adc_config.adc_enable = AUD_ADC_DISABLE;
adc_config.line_enable = AUD_ADC_LINE_DISABLE;
adc_config.dtmf_enable = AUD_DTMF_DISABLE;
adc_config.adc_hpf2_coef_B2 = 0;
adc_config.adc_hpf2_bypass_enable = AUD_ADC_HPF_BYPASS_ENABLE;
adc_config.adc_hpf1_bypass_enable = AUD_ADC_HPF_BYPASS_ENABLE;
adc_config.adc_set_gain = 0x2d;
adc_config.adc_samp_edge = AUD_ADC_SAMP_EDGE_RISING;
adc_config.adc_hpf2_coef_B0 = 0;
adc_config.adc_hpf2_coef_B1 = 0;
adc_config.adc_hpf2_coef_A0 = 0;
adc_config.adc_hpf2_coef_A1 = 0;
adc_config.dtmf_wr_threshold = 8;
adc_config.adcl_wr_threshold = 8;
adc_config.dtmf_int_enable = AUD_DTMF_INT_DISABLE;
adc_config.adcl_int_enable = AUD_ADCL_INT_DISABLE;
adc_config.loop_adc2dac = AUD_LOOP_ADC2DAC_DISABLE;
adc_config.agc_noise_thrd = 101;
adc_config.agc_noise_high = 101;
adc_config.agc_noise_low = 160;
adc_config.agc_noise_min = 1;
adc_config.agc_noise_tout = 0;
adc_config.agc_high_dur = 3;
adc_config.agc_low_dur = 3;
adc_config.agc_min = 1;
adc_config.agc_max = 4;
adc_config.agc_ng_method = AUD_AGC_NG_METHOD_MUTE;
adc_config.agc_ng_enable = AUD_AGC_NG_DISABLE;
adc_config.agc_decay_time = AUD_AGC_DECAY_TIME_128;
adc_config.agc_attack_time = AUD_AGC_ATTACK_TIME_128;
adc_config.agc_high_thrd = 18;
adc_config.agc_low_thrd = 0;
adc_config.agc_iir_coef = AUD_AGC_IIR_COEF_1_1024;
adc_config.agc_enable = AUD_AGC_DISABLE;
adc_config.manual_pga_value = 0;
adc_config.manual_pga_enable = AUD_GAC_MANUAL_PGA_DISABLE;
adc_config.adc_fracmod_manual = AUD_ADC_TRACMOD_MANUAL_DISABLE;
adc_config.adc_fracmod = 0;
/* init audio driver and config adc */
ret = bk_aud_driver_init();
if (ret != BK_OK)
{
os_printf("cp1: init audio driver fail \r\n");
goto aud_adc_exit;
}
ret = bk_aud_adc_init(AUD_ADC_WORK_MODE_ADC, &adc_config, NULL);
if (ret != BK_OK)
{
os_printf("cp1: init audio adc fail \r\n");
goto aud_adc_exit;
}
return BK_OK;
aud_adc_exit:
os_printf("cp1: audio adc config fail \r\n");
bk_aud_driver_deinit();
return BK_FAIL;
}
static void audio_dma_adc_finish_isr(void)
{
bk_gpio_pull_up(GPIO_2);
bk_gpio_pull_down(GPIO_2);
}
static bk_err_t audio_adc_dma_config(dma_id_t dma_id, int32_t *ring_buff_addr, uint32_t ring_buff_size, uint32_t transfer_len)
{
bk_err_t ret = BK_OK;
dma_config_t dma_config;
uint32_t adc_port_addr;
dma_config.mode = DMA_WORK_MODE_REPEAT;
dma_config.chan_prio = 1;
dma_config.src.dev = DMA_DEV_AUDIO;
dma_config.dst.dev = DMA_DEV_DTCM;
dma_config.src.width = DMA_DATA_WIDTH_16BITS;
dma_config.dst.width = DMA_DATA_WIDTH_32BITS;
/* get adc fifo address */
if (bk_aud_get_adc_fifo_addr(&adc_port_addr) != BK_OK)
{
os_printf("get adc fifo address failed\r\n");
return BK_FAIL;
}
else
{
dma_config.src.addr_inc_en = DMA_ADDR_INC_ENABLE;
dma_config.src.addr_loop_en = DMA_ADDR_LOOP_ENABLE;
dma_config.src.start_addr = adc_port_addr;
dma_config.src.end_addr = adc_port_addr + 4;
}
dma_config.dst.addr_inc_en = DMA_ADDR_INC_ENABLE;
dma_config.dst.addr_loop_en = DMA_ADDR_LOOP_ENABLE;
dma_config.dst.start_addr = (uint32_t)ring_buff_addr;
dma_config.dst.end_addr = (uint32_t)ring_buff_addr + ring_buff_size;
/* init dma channel */
ret = bk_dma_init(dma_id, &dma_config);
if (ret != BK_OK)
{
os_printf("cp1: audio adc dma channel init fail \r\n");
return BK_FAIL;
}
/* set dma transfer length */
bk_dma_set_transfer_len(dma_id, transfer_len);
//register isr
bk_dma_register_isr(dma_id, NULL, (void *)audio_dma_adc_finish_isr);
bk_dma_enable_finish_interrupt(dma_id);
//bk_dma_set_transfer_len(dma_id, 0x20);
//bk_dma_start(dma_id);
return BK_OK;
}
void audio_adc_start(void)
{
int ret;
LOGI("%s\n", __func__);
ret = audio_adc_config();
if (ret != BK_OK)
{
os_printf("cp1: audio adc init fail \r\n");
return;
}
/* allocate free DMA channel */
aud_adc_dma_id = bk_dma_alloc(DMA_DEV_AUDIO);
if ((aud_adc_dma_id < DMA_ID_0) || (aud_adc_dma_id >= DMA_ID_MAX))
{
os_printf("malloc dma fail \r\n");
return;
}
#ifdef CONFIG_PSRAM
ret = audio_adc_dma_config(aud_adc_dma_id, (int32_t *)psram_map->aud_adc, AUD_8K_FRAME_SAMP_SIZE * 2, AUD_8K_FRAME_SAMP_SIZE);
#else
ret = audio_adc_dma_config(aud_adc_dma_id, (int32_t *)NULL, AUD_8K_FRAME_SAMP_SIZE * 2, AUD_8K_FRAME_SAMP_SIZE);
#endif
ret = bk_dma_start(aud_adc_dma_id);
if (ret != BK_OK)
{
os_printf("cp1: start dac dma fail \r\n");
return;
}
/* enable adc */
/* wait receive data and then open adc */
bk_aud_start_adc();
}
@@ -1,64 +0,0 @@
// Copyright (C) 2022 Beken Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <os/os.h>
#include <components/log.h>
#include "media_core.h"
#include "media_evt.h"
#include "aud_act.h"
#include "adc_ccb.h"
#include "dac_ccb.h"
#include <driver/int.h>
#include <os/mem.h>
#include <driver/gpio.h>
#include <driver/gpio_types.h>
#include <driver/dma.h>
#define TAG "aud_act"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
void audio_adc_open_handle(void)
{
audio_adc_start();
}
void audio_dac_open_handle(void)
{
audio_dac_start();
}
void audio_event_handle(uint32_t event, uint32_t param)
{
switch (event)
{
case EVENT_AUD_ADC_OPEN:
audio_adc_open_handle();
break;
case EVENT_AUD_DAC_OPEN:
audio_dac_open_handle();
break;
}
}
@@ -1,56 +0,0 @@
// Copyright (C) 2022 Beken Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <os/os.h>
#include <components/log.h>
#include "media_core.h"
#include "media_evt.h"
#include <driver/int.h>
#include <os/mem.h>
#include <driver/gpio.h>
#include <driver/gpio_types.h>
#include <driver/dma.h>
#define TAG "aud_act"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
bk_err_t adc_open(void)
{
media_msg_t msg;
msg.event = EVENT_AUD_ADC_OPEN;
media_send_msg(&msg);
return BK_OK;
}
bk_err_t dac_open(void)
{
media_msg_t msg;
msg.event = EVENT_AUD_DAC_OPEN;
media_send_msg(&msg);
return BK_OK;
}
@@ -1,201 +0,0 @@
// Copyright (C) 2022 Beken Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <os/os.h>
#include <components/log.h>
#include "media_core.h"
#include "aud_act.h"
#include <os/os.h>
#include <os/mem.h>
#include <os/str.h>
#include <driver/aud.h>
#include <driver/aud_types.h>
#include <driver/dma.h>
#include "aud_hal.h"
#include "sys_driver.h"
#include "aud_driver.h"
#include <driver/psram.h>
#include <modules/aec.h>
#include <modules/audio_ring_buff.h>
#include <modules/g711.h>
#include "gpio_driver.h"
#include <driver/gpio.h>
#include <soc/mapping.h>
#include "dac_ccb.h"
#define TAG "dac_ccb"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
#define AUD_8K_FRAME_SAMP_SIZE 160*2
dma_id_t aud_dac_dma_id = DMA_ID_MAX;
static bk_err_t audio_dac_config(void)
{
bk_err_t ret = BK_OK;
aud_dac_config_t dac_config;
dac_config.dac_enable = AUD_DAC_DISABLE;
dac_config.samp_rate = AUD_DAC_SAMP_RATE_SOURCE_8K;
dac_config.dac_hpf2_coef_B2 = 0x3A22;
dac_config.dac_hpf2_bypass_enable = AUD_DAC_HPF_BYPASS_ENABLE;
dac_config.dac_hpf1_bypass_enable = AUD_DAC_HPF_BYPASS_ENABLE;
dac_config.dac_set_gain = 0x2D; //default 2D 3F 15
dac_config.dac_clk_invert = AUD_DAC_CLK_INVERT_RISING;
dac_config.dac_hpf2_coef_B0 = 0x3A22;
dac_config.dac_hpf2_coef_B1 = 0x8BBF;
dac_config.dac_hpf2_coef_A1 = 0x751C;
dac_config.dac_hpf2_coef_A2 = 0xC9E6;
dac_config.dacr_rd_threshold = 0x4;
dac_config.dacl_rd_threshold = 0x4;
dac_config.dacr_int_enable = 0x0;
dac_config.dacl_int_enable = 0x0;
dac_config.dac_filt_enable = AUD_DAC_FILT_DISABLE;
dac_config.dac_fracmod_manual_enable = AUD_DAC_FRACMOD_MANUAL_DISABLE;
dac_config.dac_fracmode_value = 0x0;
/* init audio driver and config dac */
ret = bk_aud_driver_init();
if (ret != BK_OK)
{
os_printf("cp1: init audio driver fail \r\n");
goto aud_dac_exit;
}
ret = bk_aud_dac_init(&dac_config);
if (ret != BK_OK)
{
os_printf("cp1: init audio dac fail \r\n");
goto aud_dac_exit;
}
return BK_OK;
aud_dac_exit:
os_printf("cp1: audio dac config fail \r\n");
bk_aud_driver_deinit();
return BK_FAIL;
}
static void audio_dma_dac_finish_isr(void)
{
bk_gpio_pull_up(GPIO_3);
bk_gpio_pull_down(GPIO_3);
}
static bk_err_t audio_dac_dma_config(dma_id_t dma_id, int32_t *ring_buff_addr, uint32_t ring_buff_size, uint32_t transfer_len)
{
bk_err_t ret = BK_OK;
dma_config_t dma_config;
uint32_t dac_port_addr;
dma_config.mode = DMA_WORK_MODE_REPEAT;
dma_config.chan_prio = 1;
dma_config.src.dev = DMA_DEV_DTCM;
dma_config.dst.dev = DMA_DEV_AUDIO;
dma_config.src.width = DMA_DATA_WIDTH_32BITS;
dma_config.dst.width = DMA_DATA_WIDTH_32BITS;
/* get dac fifo address */
if (bk_aud_get_dac_fifo_addr(&dac_port_addr) != BK_OK)
{
os_printf("get dac fifo address failed\r\n");
return BK_FAIL;
}
else
{
dma_config.dst.addr_inc_en = DMA_ADDR_INC_ENABLE;
dma_config.dst.addr_loop_en = DMA_ADDR_LOOP_ENABLE;
dma_config.dst.start_addr = dac_port_addr;
dma_config.dst.end_addr = dac_port_addr + 4;
}
dma_config.src.addr_inc_en = DMA_ADDR_INC_ENABLE;
//dma_config.src.addr_loop_en = DMA_ADDR_LOOP_ENABLE;
dma_config.src.start_addr = (uint32_t)ring_buff_addr;
dma_config.src.end_addr = (uint32_t)(ring_buff_addr) + ring_buff_size;
/* init dma channel */
ret = bk_dma_init(dma_id, &dma_config);
if (ret != BK_OK)
{
os_printf("cp1: audio dac dma channel init fail \r\n");
return BK_FAIL;
}
/* set dma transfer length */
bk_dma_set_transfer_len(dma_id, transfer_len);
//register isr
bk_dma_register_isr(dma_id, NULL, (void *)audio_dma_dac_finish_isr);
bk_dma_enable_finish_interrupt(dma_id);
//bk_dma_set_transfer_len(dma_id, 0x20);
//bk_dma_start(dma_id);
return BK_OK;
}
void audio_dac_start(void)
{
int ret;
LOGI("%s\n", __func__);
ret = audio_dac_config();
if (ret != BK_OK)
{
os_printf("cp1: audio dac init fail \r\n");
return;
}
/* allocate free DMA channel */
aud_dac_dma_id = bk_dma_alloc(DMA_DEV_AUDIO);
if ((aud_dac_dma_id < DMA_ID_0) || (aud_dac_dma_id >= DMA_ID_MAX))
{
os_printf("malloc dma fail \r\n");
return;
}
#ifdef CONFIG_PSRAM
ret = audio_dac_dma_config(aud_dac_dma_id, (int32_t *)psram_map->aud_dac, AUD_8K_FRAME_SAMP_SIZE, AUD_8K_FRAME_SAMP_SIZE);
#else
ret = audio_dac_dma_config(aud_dac_dma_id, (int32_t *)NULL, AUD_8K_FRAME_SAMP_SIZE, AUD_8K_FRAME_SAMP_SIZE);
#endif
ret = bk_dma_start(aud_dac_dma_id);
if (ret != BK_OK)
{
os_printf("cp1: start dac dma fail \r\n");
return;
}
/* enable dac */
/* wait receive data and then open dac */
bk_aud_start_dac();
}
@@ -1,35 +0,0 @@
// Copyright (C) 2022 Beken Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <common/bk_include.h>
#include "media_evt.h"
#include <driver/dvp_camera_types.h>
#ifdef __cplusplus
extern "C" {
#endif
bk_err_t bk_dvp_camera_open(media_ppi_t ppi, dvp_mode_t mode);
bk_err_t bk_dvp_camera_close(void);
bk_err_t bk_uvc_camera_open(media_ppi_t ppi);
bk_err_t bk_uvc_camera_start(void);
bk_err_t bk_uvc_camera_stop(void);
bk_err_t bk_uvc_camera_close(void);
bk_err_t bk_uvc_camera_param_set(param_pak_t *param);
#ifdef __cplusplus
}
#endif
@@ -1,299 +0,0 @@
// Copyright (C) 2022 Beken Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <os/os.h>
#include <components/log.h>
#include "media_core.h"
#include "camera_act.h"
#include "media_evt.h"
#include "storage_act.h"
#include <driver/int.h>
#include <os/mem.h>
#include <driver/gpio.h>
#include <driver/gpio_types.h>
#include <driver/dma.h>
#include <driver/i2c.h>
#include <driver/jpeg_enc.h>
#include <driver/jpeg_enc_types.h>
#include "camera.h"
#include "frame_buffer.h"
#include <driver/dvp_camera.h>
#include <driver/dvp_camera_types.h>
#include <modules/ble.h>
#include <driver/timer.h>
#define TAG "cam_act"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
#define DEBUG_INTERVAL (1000 * 2)
extern bk_err_t pm_core_bus_clock_ctrl(uint32_t cksel_core, uint32_t ckdiv_core, uint32_t ckdiv_bus, uint32_t ckdiv_cpu0, uint32_t ckdiv_cpu1);
extern void transfer_dump(uint32_t ms);
media_debug_t *media_debug = NULL;
media_debug_t *media_debug_cached = NULL;
camera_info_t camera_info;
static void camera_debug_dump(timer_id_t timer_id)
{
transfer_dump(DEBUG_INTERVAL);
uint16_t jpg = (media_debug->isr_jpeg - media_debug_cached->isr_jpeg) / 2;
uint16_t dec = (media_debug->isr_decoder - media_debug_cached->isr_decoder) / 2;
uint16_t lcd = (media_debug->isr_lcd - media_debug_cached->isr_lcd) / 2;
uint16_t fps = (media_debug->fps_lcd - media_debug_cached->fps_lcd) / 2;
uint16_t wifi = (media_debug->fps_wifi - media_debug_cached->fps_wifi) / 2;
uint16_t err_dec = (media_debug->err_dec - media_debug_cached->err_dec) / 2;
media_debug_cached->isr_jpeg = media_debug->isr_jpeg;
media_debug_cached->isr_decoder = media_debug->isr_decoder;
media_debug_cached->isr_lcd = media_debug->isr_lcd;
media_debug_cached->fps_lcd = media_debug->fps_lcd;
media_debug_cached->fps_wifi = media_debug->fps_wifi;
media_debug_cached->err_dec = media_debug->err_dec;
LOGI("jpg: %d[%d], dec: %d[%d, %d], lcd: %d[%d], fps: %d[%d], wifi: %d[%d]\n",
jpg, media_debug->isr_jpeg,
dec, media_debug->isr_decoder, err_dec,
lcd, media_debug->isr_lcd,
fps, media_debug->fps_lcd,
wifi, media_debug->fps_wifi);
}
void camera_dvp_open_handle(param_pak_t *param, dvp_mode_t mode)
{
int ret = 0;
LOGI("%s\n", __func__);
if (CAMERA_STATE_DISABLED != get_camera_state())
{
LOGI("%s already opened\n", __func__);
ret = kNoErr;
goto out;
}
//pm_core_bus_clock_ctrl(2, 0, 1, 0, 0);
frame_buffer_enable(true);
ret = bk_dvp_camera_open(param->param, mode);
if (ret != kNoErr)
{
LOGE("%s open failed\n", __func__);
goto out;
}
set_camera_state(CAMERA_STATE_ENABLED);
if (camera_info.debug)
{
bk_timer_start(TIMER_ID1, DEBUG_INTERVAL, camera_debug_dump);
}
out:
MEDIA_EVT_RETURN(param, ret);
}
void camera_dvp_close_handle(param_pak_t *param)
{
int ret = 0;
LOGI("%s\n", __func__);
if (CAMERA_STATE_DISABLED == get_camera_state())
{
LOGI("%s already close\n", __func__);
ret = kNoErr;
goto out;
}
bk_dvp_camera_close();
set_camera_state(CAMERA_STATE_DISABLED);
if (camera_info.debug)
{
bk_timer_stop(TIMER_ID1);
}
frame_buffer_enable(false);
//pm_core_bus_clock_ctrl(3, 1, 1, 0, 0);
out:
MEDIA_EVT_RETURN(param, ret);
}
#ifdef CONFIG_USB_UVC
void camera_uvc_open_handle(param_pak_t *param)
{
int ret = 0;
LOGI("%s\n", __func__);
if (CAMERA_STATE_DISABLED != get_camera_state())
{
LOGI("%s already opened\n", __func__);
ret = kNoErr;
goto out;
}
if (bk_ble_get_env_state())
{
LOGI("bluetooth is enabled, shutdown bluetooth\n");
bk_ble_deinit();
rtos_delay_milliseconds(900);
}
else
{
LOGI("bluetooth state: %d\n", bk_ble_get_env_state());
}
//pm_core_bus_clock_ctrl(2, 0, 1, 0, 0);
frame_buffer_enable(true);
ret = bk_uvc_camera_open(param->param);
if (ret != kNoErr)
{
LOGE("%s open failed\n", __func__);
goto out;
}
set_camera_state(CAMERA_STATE_ENABLED);
if (camera_info.debug)
{
bk_timer_start(TIMER_ID1, DEBUG_INTERVAL, camera_debug_dump);
}
out:
MEDIA_EVT_RETURN(param, ret);
}
void camera_uvc_close_handle(param_pak_t *param)
{
int ret = 0;
LOGI("%s\n", __func__);
if (CAMERA_STATE_DISABLED == get_camera_state())
{
LOGI("%s already close\n", __func__);
ret = kNoErr;
goto out;
}
if (camera_info.debug)
{
bk_timer_stop(TIMER_ID1);
}
bk_uvc_camera_close();
set_camera_state(CAMERA_STATE_DISABLED);
frame_buffer_enable(false);
//pm_core_bus_clock_ctrl(3, 1, 1, 0, 0);
LOGI("uvc close success!\n");
out:
MEDIA_EVT_RETURN(param, ret);
}
#endif
void camera_event_handle(uint32_t event, uint32_t param)
{
switch (event)
{
case EVENT_CAM_DVP_JPEG_OPEN_IND:
camera_dvp_open_handle((param_pak_t *)param, DVP_MODE_JPG);
break;
case EVENT_CAM_DVP_YUV_OPEN_IND:
camera_dvp_open_handle((param_pak_t *)param, DVP_MODE_YUV);
break;
case EVENT_CAM_DVP_CLOSE_IND:
camera_dvp_close_handle((param_pak_t *)param);
break;
#ifdef CONFIG_USB_UVC
case EVENT_CAM_UVC_OPEN_IND:
camera_uvc_open_handle((param_pak_t *)param);
break;
case EVENT_CAM_UVC_CLOSE_IND:
camera_uvc_close_handle((param_pak_t *)param);
break;
#endif
}
}
camera_state_t get_camera_state(void)
{
return camera_info.state;
}
void set_camera_state(camera_state_t state)
{
camera_info.state = state;
}
void camera_init(void)
{
if (media_debug == NULL)
{
media_debug = (media_debug_t*)os_malloc(sizeof(media_debug_t));
if (media_debug == NULL)
{
LOGE("malloc media_debug fail\n");
}
}
if (media_debug_cached == NULL)
{
media_debug_cached = (media_debug_t*)os_malloc(sizeof(media_debug_t));
if (media_debug_cached == NULL)
{
LOGE("malloc media_debug_cached fail\n");
}
}
camera_info.state = CAMERA_STATE_DISABLED;
camera_info.debug = true;
}
@@ -1,100 +0,0 @@
// Copyright (C) 2022 Beken Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <os/os.h>
#include <components/log.h>
#include "media_core.h"
#include "camera_act.h"
#include "lcd_act.h"
#include "storage_act.h"
#include <driver/int.h>
#include <os/mem.h>
#include <driver/gpio.h>
#include <driver/gpio_types.h>
#include <driver/dma.h>
#include <driver/i2c.h>
#include <driver/jpeg_enc.h>
#include <driver/jpeg_enc_types.h>
#include <driver/dvp_camera.h>
#include <driver/dvp_camera_types.h>
#include "frame_buffer.h"
#define TAG "dvp"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
void frame_buffer_jpg_complete(frame_buffer_t *buffer)
{
frame_buffer_generate_complete(buffer, FRAME_JPEG);
}
frame_buffer_t *frame_buffer_jpg_alloc(void)
{
return frame_buffer_alloc(FRAME_JPEG);
}
void frame_buffer_yuv_complete(frame_buffer_t *buffer)
{
frame_buffer_generate_complete(buffer, FRAME_DISPLAY);
}
frame_buffer_t *frame_buffer_yuv_alloc(void)
{
return frame_buffer_alloc(FRAME_DISPLAY);
}
bk_err_t bk_dvp_camera_open(media_ppi_t ppi, dvp_mode_t mode)
{
int ret = BK_OK;
dvp_camera_config_t config;
if (DVP_MODE_JPG == mode)
{
config.ppi = ppi;
config.mode = DVP_MODE_JPG;
config.frame_set_ppi = frame_buffer_set_ppi;
config.frame_complete = frame_buffer_jpg_complete;
config.frame_alloc = frame_buffer_jpg_alloc;
ret = bk_dvp_camera_driver_init(&config);
}
else if (DVP_MODE_YUV == mode)
{
config.ppi = ppi;
config.mode = DVP_MODE_YUV;
config.frame_set_ppi = frame_buffer_set_ppi;
config.frame_complete = frame_buffer_yuv_complete;
config.frame_alloc = frame_buffer_yuv_alloc;
ret = bk_dvp_camera_driver_init(&config);
}
return ret;
}
bk_err_t bk_dvp_camera_close(void)
{
bk_dvp_camera_driver_deinit();
return 0;
}
@@ -1,103 +0,0 @@
// Copyright (C) 2022 Beken Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <os/os.h>
#include <components/log.h>
#include "camera_act.h"
#include "media_evt.h"
#include "media_app.h"
#include <os/mem.h>
#include <driver/uvc_camera.h>
#include "frame_buffer.h"
#define TAG "uvc"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
#ifdef CONFIG_USB_UVC
uvc_camera_device_t uvc_camera_device =
{
.width = 640,
.height = 480,
.fps = 25,
};
void frame_buffer_uvc_jpg_complete(frame_buffer_t *buffer)
{
frame_buffer_generate_complete(buffer, FRAME_JPEG);
}
frame_buffer_t *frame_buffer_uvc_jpg_alloc(void)
{
return frame_buffer_alloc(FRAME_JPEG);
}
void uvc_device_disconnect_callback(void)
{
LOGI("%s\n", __func__);
media_app_camera_close(APP_CAMERA_UVC);
}
const uvc_camera_config_t uvc_camera_config =
{
.device = &uvc_camera_device,
.frame_set_ppi = frame_buffer_set_ppi,
.frame_complete = frame_buffer_uvc_jpg_complete,
.frame_alloc = frame_buffer_uvc_jpg_alloc,
.uvc_disconnect = uvc_device_disconnect_callback,
};
bk_err_t bk_uvc_camera_open(media_ppi_t ppi)
{
if (ppi != 0)
{
uvc_camera_device.width = ppi >> 16;
uvc_camera_device.height = ppi & 0xFFFF;
}
return bk_uvc_camera_driver_init(&uvc_camera_config);
}
bk_err_t bk_uvc_camera_start(void)
{
return bk_uvc_camera_driver_start();
}
bk_err_t bk_uvc_camera_stop(void)
{
return bk_uvc_camera_driver_stop();
}
bk_err_t bk_uvc_camera_close(void)
{
bk_uvc_camera_driver_deinit();
return 0;
}
bk_err_t bk_uvc_camera_param_set(param_pak_t *param)
{
return bk_uvc_camera_set_config((uvc_camera_device_t *)param->param);
}
#endif
@@ -1,799 +0,0 @@
// Copyright (C) 2022 Beken Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <os/os.h>
#include <components/log.h>
#include "media_core.h"
#include "media_evt.h"
#include "storage_act.h"
#include "lcd_act.h"
#include "frame_buffer.h"
#include <driver/int.h>
#include <os/mem.h>
#include <driver/gpio.h>
#include <driver/gpio_types.h>
#include <driver/dma.h>
#include <driver/jpeg_enc.h>
#include <driver/jpeg_enc_types.h>
#include <driver/dvp_camera.h>
#include <driver/dvp_camera_types.h>
#include <soc/mapping.h>
#include <driver/lcd.h>
#include <driver/dma.h>
#include <driver/gpio.h>
#include <driver/jpeg_dec.h>
#include <driver/dma2d.h>
//#include <lcd_dma2d_config.h>
#include <driver/jpeg_dec_types.h>
#include "modules/image_scale.h"
//#include "lcd_blend_config.h"
#include <driver/uvc_camera_types.h>
#include <driver/uvc_camera.h>
#include <modules/pm.h>
#include <driver/timer.h>
#define TAG "lcd"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
extern media_debug_t *media_debug;
lcd_info_t lcd_info = {0};
uint32_t decoder_size;
void lcd_frame_pingpong_insert(frame_buffer_t *buffer)
{
if (lcd_info.display_frame == NULL)
{
lcd_info.display_frame = buffer;
lcd_driver_set_display_base_addr((uint32_t)lcd_info.display_frame->frame);
lcd_driver_display_enable();
LOGD("display start\n");
}
else
{
GLOBAL_INT_DECLARATION();
GLOBAL_INT_DISABLE();
if (lcd_info.pingpong_frame != NULL)
{
frame_buffer_free_request(lcd_info.pingpong_frame, MODULE_DISPLAY);
}
lcd_info.pingpong_frame = buffer;
GLOBAL_INT_RESTORE();
}
}
static void lcd_act_complete_callback(void)
{
media_debug->isr_lcd++;
if (lcd_info.display_frame == NULL)
{
LOGW("display frame should not be NULL\n");
return;
}
if (lcd_info.pingpong_frame != NULL)
{
frame_buffer_free_request(lcd_info.display_frame, MODULE_DISPLAY);
lcd_info.display_frame = lcd_info.pingpong_frame;
lcd_info.pingpong_frame = NULL;
lcd_driver_set_display_base_addr((uint32_t)lcd_info.display_frame->frame);
media_debug->fps_lcd++;
}
//LOGI("rgb %p\n", lcd_info.display_frame->frame);
lcd_driver_display_continue();
}
#if 0
static void lcd_act_jpeg_dec_dump(uint8_t *src, uint32_t size)
{
uint32_t i;
LOGE("dump: ");
for (i = 0; i < size; i++)
{
os_printf("%02X ", src[i]);
}
os_printf("\n");
}
#endif
static void jpeg_dec_eof_cb(jpeg_dec_res_t *result)
{
media_debug->isr_decoder++;
//bk_gpio_pull_up(GPIO_8);
if (lcd_info.step_mode == false)
{
bk_timer_stop(TIMER_ID3);
}
else
{
if (lcd_info.step_trigger == true)
{
LOGI("decoder frame %u complete(%u:%u)\n", lcd_info.jpeg_frame->sequence, lcd_info.jpeg_frame->length, result->size);
lcd_info.step_trigger = false;
}
lcd_frame_pingpong_insert(lcd_info.decoder_frame);
return;
}
decoder_size = result->size;
if (result->ok == false)
{
media_msg_t msg;
//LOGE("decoder failed, %u %u\n", result->size, lcd_info.jpeg_frame->length);
//lcd_act_jpeg_dec_dump(lcd_info.jpeg_frame->frame + lcd_info.jpeg_frame->length - 15, 15);
frame_buffer_free_request(lcd_info.decoder_frame, MODULE_DISPLAY);
msg.event = EVENT_COM_FRAME_DECODER_FREE_IND;
msg.param = (uint32_t)lcd_info.jpeg_frame;
media_send_msg(&msg);
lcd_info.jpeg_frame = NULL;
media_debug->err_dec++;
return;
}
if (lcd_info.rotate == false)
{
lcd_frame_pingpong_insert(lcd_info.decoder_frame);
lcd_info.decoder_frame = NULL;
if (lcd_info.jpeg_frame && true == frame_buffer_get_state())
{
media_msg_t msg;
LOGD("free decoder frame: %u\n", lcd_info.jpeg_frame->sequence);
msg.event = EVENT_COM_FRAME_DECODER_FREE_IND;
msg.param = (uint32_t)lcd_info.jpeg_frame;
media_send_msg(&msg);
lcd_info.jpeg_frame = NULL;
}
else
{
LOGD("fjpgeof frame: %p, %d\n", lcd_info.jpeg_frame, frame_buffer_get_state());
}
}
else
{
lcd_info.rotate_frame = frame_buffer_alloc(FRAME_DISPLAY);
lcd_info.rotate_frame->sequence = lcd_info.decoder_frame->sequence;
#if 1
media_msg_t msg;
msg.event = EVENT_LCD_ROTATE_RIGHT_CMD;
msg.param = (uint32_t)&lcd_info;
media_send_msg(&msg);
#else
media_msg_t msg;
msg.event = EVENT_LCD_FRAME_LOCAL_ROTATE_IND;
msg.param = (uint32_t)&lcd_info;
media_send_msg(&msg);
#endif
}
//bk_gpio_pull_down(GPIO_8);
}
static void lcd_act_decoder_timeout(timer_id_t timer_id)
{
bk_timer_stop(TIMER_ID3);
LOGI("decoder timeout\n");
bk_jpeg_dec_stop();
frame_buffer_free_request(lcd_info.decoder_frame, MODULE_DISPLAY);
lcd_info.decoder_frame = NULL;
if (lcd_info.jpeg_frame && true == frame_buffer_get_state())
{
media_msg_t msg;
LOGI("free decoder frame: %u\n", lcd_info.jpeg_frame->sequence);
msg.event = EVENT_COM_FRAME_DECODER_FREE_IND;
msg.param = (uint32_t)lcd_info.jpeg_frame;
media_send_msg(&msg);
lcd_info.jpeg_frame = NULL;
}
}
void lcd_act_rotate_complete(frame_buffer_t *frame)
{
frame_buffer_free_request(lcd_info.decoder_frame, MODULE_DISPLAY);
if (frame != lcd_info.rotate_frame)
{
LOGE("frame not match\n");
}
lcd_frame_pingpong_insert(lcd_info.rotate_frame);
if (lcd_info.jpeg_frame && true == frame_buffer_get_state())
{
media_msg_t msg;
LOGD("free decoder frame: %u\n", lcd_info.jpeg_frame->sequence);
msg.event = EVENT_COM_FRAME_DECODER_FREE_IND;
msg.param = (uint32_t)lcd_info.jpeg_frame;
media_send_msg(&msg);
lcd_info.jpeg_frame = NULL;
}
}
uint8_t lcd_frame_complete_callback(frame_buffer_t *buffer)
{
bool lock = false;
if (buffer->type == FRAME_JPEG)
{
media_msg_t msg;
msg.event = EVENT_LCD_FRAME_COMPLETE_IND;
msg.param = (uint32_t)buffer;
media_send_msg(&msg);
}
else if (buffer->type == FRAME_DISPLAY)
{
lcd_frame_pingpong_insert(buffer);
}
return lock;
}
int lcd_act_driver_init(uint32_t lcd_ppi)
{
int ret = BK_FAIL;
dvp_camera_device_t *dvp_device = NULL;
bool yuv_mode = false;
LOGI("%s, ppi: %dX%d\n", __func__, lcd_ppi >> 16, lcd_ppi & 0xFFFF);
if (lcd_info.state == LCD_STATE_ENABLED)
{
LOGE("alread enable\n", __func__);
return ret;
}
dvp_device = bk_dvp_camera_get_device();
if (dvp_device == NULL || dvp_device->id == ID_UNKNOW)
{
LOGE("dvp camera was not init\n");
#if (CONFIG_USB_UVC)
uvc_camera_device_t *uvc_device = NULL;
uvc_device = bk_uvc_camera_get_device();
if (uvc_device == NULL)
{
LOGE("uvc camera was not init\n");
return BK_FAIL;
}
lcd_info.src_pixel_x = uvc_device->width;
lcd_info.src_pixel_y = uvc_device->height;
lcd_info.camera = UVC_CAMERA;
#else
return BK_FAIL;
#endif
}
else
{
lcd_info.src_pixel_x = ppi_to_pixel_x(dvp_device->ppi);
lcd_info.src_pixel_y = ppi_to_pixel_y(dvp_device->ppi);
if (dvp_device->mode == DVP_MODE_YUV)
{
yuv_mode = true;
}
lcd_info.camera = DVP_CAMERA;
}
ret = bk_jpeg_dec_driver_init();
media_debug->fps_lcd = 0;
media_debug->isr_decoder = 0;
media_debug->isr_lcd = 0;
media_debug->err_dec = 0;
if (ret != BK_OK)
{
LOGE("bk_jpeg_dec_driver_init failed\n");
return ret;
}
lcd_info.lcd_pixel_x = ppi_to_pixel_x(lcd_ppi);
lcd_info.lcd_pixel_y = ppi_to_pixel_y(lcd_ppi);
lcd_info.display_frame = NULL;
lcd_info.pingpong_frame = NULL;
lcd_info.jpeg_frame = NULL;
lcd_info.decoder_frame = NULL;
lcd_info.step_mode = false;
lcd_info.step_trigger = false;
LOGI("%s Camera PPI: %dX%d\n", __func__, lcd_info.src_pixel_x, lcd_info.src_pixel_y);
lcd_config_t lcd_config;
if (lcd_ppi == PPI_1024X600)
{
lcd_config.device = get_lcd_device_by_id(LCD_DEVICE_HX8282);
}
else if (lcd_ppi == PPI_320X480)
{
lcd_config.device = get_lcd_device_by_id(LCD_DEVICE_ST7796S);
}
else if (lcd_ppi == PPI_480X800)
{
lcd_config.device = get_lcd_device_by_id(LCD_DEVICE_GC9503V);
}
else
{
lcd_config.device = get_lcd_device_by_id(LCD_DEVICE_ST7282);
}
lcd_config.complete_callback = lcd_act_complete_callback;
if (lcd_info.rotate == false)
{
lcd_config.pixel_x = lcd_info.src_pixel_x;
lcd_config.pixel_y = lcd_info.src_pixel_y;
}
else
{
lcd_config.pixel_x = ppi_to_pixel_x(lcd_config.device->ppi);
lcd_config.pixel_y = ppi_to_pixel_y(lcd_config.device->ppi);
}
lcd_info.pixel_size = get_ppi_size(lcd_config.device->ppi);
if (yuv_mode)
{
lcd_config.fmt = LCD_FMT_ORGINAL_YUYV;
}
else
{
frame_buffer_display_frame_init();
if (lcd_info.rotate)
{
lcd_config.fmt = LCD_FMT_ORGINAL_YUYV;
}
else
{
lcd_config.fmt = LCD_FMT_VUYY;
}
bk_jpeg_dec_isr_register(DEC_END_OF_FRAME, jpeg_dec_eof_cb);
}
lcd_driver_init(&lcd_config);
#if CONFIG_PWM
lcd_driver_set_backlight(100);
#endif
lcd_info.state = LCD_STATE_ENABLED;
if (yuv_mode)
{
frame_buffer_frame_register(MODULE_DISPLAY, lcd_frame_complete_callback);
}
else
{
frame_buffer_frame_register(MODULE_DECODER, lcd_frame_complete_callback);
}
LOGI("%s successful\n", __func__);
return ret;
}
void lcd_open_handle(param_pak_t *param)
{
int ret = BK_OK;
//media_msg_t msg;
LOGI("%s\n", __func__);
if (LCD_STATE_ENABLED == get_lcd_state())
{
LOGW("%s already open\n", __func__);
goto out;
}
bk_pm_module_vote_cpu_freq(PM_DEV_ID_DISP, PM_CPU_FRQ_320M);
ret = lcd_act_driver_init(param->param);
set_lcd_state(LCD_STATE_ENABLED);
out:
MEDIA_EVT_RETURN(param, ret);
}
void lcd_close_handle(param_pak_t *param)
{
int ret = BK_OK;
dvp_camera_device_t *dvp_device = NULL;
bool yuv_mode = false;
LOGI("%s\n", __func__);
if (LCD_STATE_DISABLED == get_lcd_state())
{
LOGW("%s already close\n", __func__);
goto out;
}
dvp_device = bk_dvp_camera_get_device();
lcd_driver_deinit();
lcd_info.rotate = false;
if (dvp_device != NULL
&& dvp_device->id != ID_UNKNOW
&& dvp_device->mode == DVP_MODE_YUV)
{
yuv_mode = true;
}
if (yuv_mode)
{
frame_buffer_frame_deregister(MODULE_DISPLAY);
}
else
{
bk_timer_stop(TIMER_ID3);
bk_jpeg_dec_driver_deinit();
frame_buffer_frame_deregister(MODULE_DECODER);
}
if (lcd_info.jpeg_frame)
{
media_msg_t msg;
msg.event = EVENT_COM_FRAME_DECODER_FREE_IND;
msg.param = (uint32_t)lcd_info.jpeg_frame;
media_send_msg(&msg);
lcd_info.jpeg_frame = NULL;
}
if (lcd_info.decoder_frame)
{
frame_buffer_free_request(lcd_info.decoder_frame, MODULE_DISPLAY);
lcd_info.decoder_frame = NULL;
}
if (lcd_info.pingpong_frame)
{
frame_buffer_free_request(lcd_info.pingpong_frame, MODULE_DISPLAY);
lcd_info.pingpong_frame = NULL;
}
if (lcd_info.display_frame)
{
frame_buffer_free_request(lcd_info.display_frame, MODULE_DISPLAY);
lcd_info.display_frame = NULL;
}
set_lcd_state(LCD_STATE_DISABLED);
bk_pm_module_vote_cpu_freq(PM_DEV_ID_DISP, PM_CPU_FRQ_DEFAULT);
LOGI("%s complete\n", __func__);
out:
MEDIA_EVT_RETURN(param, ret);
}
void lcd_set_backligth_handle(param_pak_t *param)
{
int ret = BK_OK;
LOGI("%s, levle: %d\n", __func__, param->param);
#if CONFIG_PWM
lcd_driver_set_backlight(param->param);
#endif
MEDIA_EVT_RETURN(param, ret);
}
void lcd_act_dump_decoder_frame(void)
{
storage_frame_buffer_dump(lcd_info.decoder_frame, "decoder_vuyy.yuv");
}
void lcd_act_dump_jpeg_frame(void)
{
LOGI("decoder size: %u, jpeg size: %d\n", decoder_size, lcd_info.jpeg_frame->length);
storage_frame_buffer_dump(lcd_info.jpeg_frame, "jpeg.jpg");
}
void lcd_act_dump_display_frame(void)
{
storage_frame_buffer_dump(lcd_info.display_frame, "display_vuyy.yuv");
}
bk_err_t lcd_frame_decoder(frame_buffer_t *buffer)
{
int ret = BK_FAIL;
frame_buffer_t *frame = NULL;
if (buffer->frame[0] != 0xFF || buffer->frame[1] != 0xD8)
{
ret = BK_FAIL;
LOGE("%s frame header error\n");
goto error;
}
if (lcd_info.jpeg_frame == NULL)
{
lcd_info.jpeg_frame = buffer;
frame = frame_buffer_alloc(FRAME_DISPLAY);
if (frame == NULL)
{
LOGE("%s malloc decoder frame NULL\n");
//TODO;
goto error;
}
frame->length = lcd_info.src_pixel_x * lcd_info.src_pixel_y * 2;
frame->sequence = lcd_info.jpeg_frame->sequence;
//bk_gpio_pull_up(GPIO_5);
LOGD("decoder frame: %u, %p, %p\n", lcd_info.jpeg_frame->sequence, lcd_info.jpeg_frame->frame, frame->frame);
LOGD("frame: %u, %u, %u\n", lcd_info.jpeg_frame->sequence, lcd_info.jpeg_frame->length, lcd_info.jpeg_frame->length % 4);
if (lcd_info.camera == UVC_CAMERA)
{
ret = bk_jpeg_dec_dma_start(lcd_info.jpeg_frame->length, lcd_info.jpeg_frame->frame, frame->frame);
}
else
{
ret = bk_jpeg_dec_hw_start(lcd_info.jpeg_frame->length, lcd_info.jpeg_frame->frame, frame->frame);
}
if (lcd_info.step_mode == false)
{
bk_timer_start(TIMER_ID3, 200, lcd_act_decoder_timeout);
}
//bk_gpio_pull_down(GPIO_5);
LOGD("bk_jpeg_dec_hw_start, :%d\n", ret);
}
else
{
LOGI("decoder frame not NULL\n");
}
if (ret != BK_OK)
{
LOGE("%s frame decoder error\n", __func__);
goto error;
}
lcd_info.decoder_frame = frame;
return ret;
error:
LOGE("decoder error, free frame: %u\n", buffer->sequence);
lcd_info.jpeg_frame = NULL;
media_debug->err_dec++;
if (frame != NULL)
{
frame_buffer_free_request(frame, MODULE_DISPLAY);
}
return ret;
}
void lcd_frame_complete_handle(frame_buffer_t *buffer)
{
int ret = BK_FAIL;
if (lcd_info.debug == true)
{
bk_gpio_set_output_high(GPIO_2);
}
if (buffer->type == FRAME_JPEG)
{
ret = lcd_frame_decoder(buffer);
}
else if (buffer->type == FRAME_DISPLAY)
{
//TODO
LOGE("%s frame error\n");
}
if (ret != BK_OK)
{
media_msg_t msg;
msg.event = EVENT_COM_FRAME_DECODER_FREE_IND;
msg.param = (uint32_t)buffer;
media_send_msg(&msg);
}
if (lcd_info.debug == true)
{
bk_gpio_set_output_low(GPIO_2);
}
}
void lcd_event_handle(uint32_t event, uint32_t param)
{
param_pak_t *param_pak = NULL;
switch (event)
{
case EVENT_LCD_OPEN_IND:
lcd_open_handle((param_pak_t *)param);
break;
case EVENT_LCD_ROTATE_ENABLE_IND:
{
LOGI("EVENT_LCD_ROTATE_ENABLE_IND\n");
param_pak = (param_pak_t *)param;
lcd_info.rotate = param_pak->param;
MEDIA_EVT_RETURN(param_pak, BK_OK);
}
break;
case EVENT_LCD_FRAME_COMPLETE_IND:
lcd_frame_complete_handle((frame_buffer_t *)param);
break;
case EVENT_LCD_FRAME_LOCAL_ROTATE_IND:
#if 0
lcd_act_rotate_degree90(param);
lcd_act_rotate_complete(lcd_info.rotate_frame);
#endif
break;
case EVENT_LCD_CLOSE_IND:
lcd_close_handle((param_pak_t *)param);
break;
case EVENT_LCD_SET_BACKLIGHT_IND:
lcd_set_backligth_handle((param_pak_t *)param);
break;
case EVENT_LCD_DUMP_DECODER_IND:
lcd_act_dump_decoder_frame();
param_pak = (param_pak_t *)param;
MEDIA_EVT_RETURN(param_pak, BK_OK);
break;
case EVENT_LCD_DUMP_JPEG_IND:
lcd_act_dump_jpeg_frame();
param_pak = (param_pak_t *)param;
MEDIA_EVT_RETURN(param_pak, BK_OK);
break;
case EVENT_LCD_DUMP_DISPLAY_IND:
lcd_act_dump_display_frame();
param_pak = (param_pak_t *)param;
MEDIA_EVT_RETURN(param_pak, BK_OK);
break;
case EVENT_LCD_STEP_MODE_IND:
param_pak = (param_pak_t *)param;
if (param_pak->param)
{
LOGI("step mode enable");
lcd_info.step_mode = true;
bk_timer_stop(TIMER_ID3);
}
else
{
LOGI("step mode disable");
lcd_info.step_mode = false;
}
MEDIA_EVT_RETURN(param_pak, BK_OK);
break;
case EVENT_LCD_STEP_TRIGGER_IND:
param_pak = (param_pak_t *)param;
LOGI("step trigger start");
lcd_info.step_trigger = true;
if (lcd_info.jpeg_frame && true == frame_buffer_get_state())
{
media_msg_t msg;
LOGI("free decoder frame: %u\n", lcd_info.jpeg_frame->sequence);
msg.event = EVENT_COM_FRAME_DECODER_FREE_IND;
msg.param = (uint32_t)lcd_info.jpeg_frame;
media_send_msg(&msg);
lcd_info.jpeg_frame = NULL;
}
MEDIA_EVT_RETURN(param_pak, BK_OK);
break;
}
}
lcd_state_t get_lcd_state(void)
{
return lcd_info.state;
}
void set_lcd_state(lcd_state_t state)
{
lcd_info.state = state;
}
void lcd_init(void)
{
os_memset(&lcd_info, 0, sizeof(lcd_info_t));
lcd_info.state = LCD_STATE_DISABLED;
lcd_info.debug = false;
lcd_info.rotate = false;
}
@@ -1,179 +0,0 @@
// Copyright (C) 2022 Beken Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <os/os.h>
#include <components/log.h>
#include "media_core.h"
#include "media_evt.h"
#include "lcd_act.h"
#include "frame_buffer.h"
#include <driver/int.h>
#include <os/mem.h>
#include <driver/gpio.h>
#include <driver/gpio_types.h>
#include <driver/dma.h>
#include <driver/jpeg_enc.h>
#include <driver/jpeg_enc_types.h>
#include <driver/dvp_camera.h>
#include <driver/dvp_camera_types.h>
#include <soc/mapping.h>
#include <driver/lcd.h>
#include <driver/dma.h>
#include <driver/gpio.h>
#include <driver/jpeg_dec.h>
#include <driver/dma2d.h>
//#include <lcd_dma2d_config.h>
#include <driver/jpeg_dec_types.h>
#include "modules/image_scale.h"
//#include "lcd_blend_config.h"
#include <driver/uvc_camera_types.h>
#include <driver/uvc_camera.h>
#include <driver/pwm.h>
#include "modules/image_scale.h"
#define TAG "rotate"
#include "cache.h"
#if CONFIG_SLAVE_CORE
#define MINOOR_DTCM __attribute__((section(".dtcm_sec_data ")))
#else
#define MINOOR_DTCM
#endif
#if CONFIG_SLAVE_CORE
#define MINOOR_ITCM __attribute__((section(".itcm_sec_code ")))
#else
#define MINOOR_ITCM
#endif
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
frame_buffer_t *rotate_frame = NULL;
frame_buffer_t *decoder_frame = NULL;
uint32_t lcd_width = 0;
uint32_t lcd_height = 0;
lcd_info_t *lcd_info_ptr = NULL;
#define BLOCK_WIDTH (40)
#define BLOCK_HEIGHT (80)
#define BLOCK_SIZE (BLOCK_WIDTH * BLOCK_HEIGHT * 2)
MINOOR_DTCM uint8_t rx_block[BLOCK_SIZE];
MINOOR_DTCM uint8_t tx_block[BLOCK_SIZE];
void rotate_complete(frame_buffer_t *frame)
{
media_msg_t msg;
msg.event = EVENT_LCD_ROTATE_RIGHT_COMP_EVT;
msg.param = (uint32_t)frame;
media_send_msg(&msg);
}
MINOOR_ITCM void memcpy_word(uint32_t *dst, uint32_t *src, uint32_t size)
{
uint32_t i = 0;
for (i = 0; i < size; i++)
{
dst[i] = src[i];
}
}
MINOOR_ITCM void lcd_act_rotate_degree90(uint32_t param)
{
lcd_info_ptr = (lcd_info_t *)param;
uint32_t i, j, k;
uint8_t *cp_ptr = NULL;
uint16_t src_width, src_height;
decoder_frame = lcd_info_ptr->decoder_frame;
rotate_frame = lcd_info_ptr->rotate_frame;
src_width = lcd_info_ptr->src_pixel_x;
src_height = lcd_info_ptr->src_pixel_y;
lcd_width = lcd_info_ptr->lcd_pixel_x;
lcd_height = lcd_info_ptr->lcd_pixel_y;
#if(1) // cpu1 cache enable
uint8_t * dst_frame_temp = rotate_frame->frame + 0x4000000;
uint8_t * src_frame_temp = decoder_frame->frame + 0x4000000;
flush_dcache(src_frame_temp, JPEG_DEC_FRAME_SIZE);
flush_dcache(dst_frame_temp, JPEG_DEC_FRAME_SIZE);
#endif
LOGD("camera %d:%d, lcd %d:%d\n", src_width, src_height, lcd_width, lcd_height);
if (lcd_width == src_width
&& lcd_width == src_width)
{
LOGD("do not rotate\n");
memcpy_word((uint32_t *)(rotate_frame->frame), (uint32_t *)decoder_frame->frame, decoder_frame->length / 4);
rotate_complete(rotate_frame);
return;
}
for (j = 0; j < (src_height / BLOCK_HEIGHT); j++)
{
for (i = 0; i < (src_width / BLOCK_WIDTH); i++)
{
for (k = 0; k < BLOCK_HEIGHT; k++)
{
#if(1) // cpu1 cache enable
cp_ptr = src_frame_temp + i * BLOCK_WIDTH * 2 + j * BLOCK_HEIGHT * src_width * 2 + k * src_width * 2;
#else
cp_ptr = decoder_frame->frame + i * BLOCK_WIDTH * 2 + j * BLOCK_HEIGHT * src_width * 2 + k * src_width * 2;
#endif
memcpy_word((uint32_t *)(rx_block + BLOCK_WIDTH * 2 * k), (uint32_t *)cp_ptr, BLOCK_WIDTH * 2 / 4);
}
vuyy_rotate_degree90(rx_block, tx_block, BLOCK_WIDTH, BLOCK_HEIGHT);
for (k = 0; k < BLOCK_WIDTH; k++)
{
#if(1) // cpu1 cache enable
cp_ptr = dst_frame_temp + (src_height / BLOCK_HEIGHT - j - 1) * BLOCK_HEIGHT * 2 + (i) * BLOCK_WIDTH * src_height * 2 + k * src_height * 2;
#else
cp_ptr = rotate_frame->frame + (src_height / BLOCK_HEIGHT - j - 1) * BLOCK_HEIGHT * 2 + (i) * BLOCK_WIDTH * src_height * 2 + k * src_height * 2;
#endif
memcpy_word((uint32_t *)cp_ptr, (uint32_t *)(tx_block + BLOCK_HEIGHT * 2 * k), BLOCK_HEIGHT * 2 / 4);
}
}
}
#if CONFIG_SLAVE_CORE
rotate_complete(rotate_frame);
#endif
}
@@ -1,101 +0,0 @@
// Copyright (C) 2022 Beken Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <os/os.h>
#include <components/log.h>
#include "media_core.h"
#include "media_evt.h"
#include "mailbox_act.h"
#include "lcd_act.h"
#include <driver/int.h>
#include <os/mem.h>
#include <driver/gpio.h>
#include <driver/gpio_types.h>
#include <driver/dma.h>
#ifdef CONFIG_MASTER_CORE
#define TAG "mb_major"
#endif
#ifdef CONFIG_SLAVE_CORE
#define TAG "mb_minor"
#endif
#include <driver/media_types.h>
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
#if CONFIG_SLAVE_CORE
void mailbox_cmd_handle(uint32_t event, uint32_t param)
{
switch (event)
{
case EVENT_LCD_DEFAULT_CMD:
LOGI("EVENT_LCD_DEFAULT_CMD \n");
media_msg_t msg;
msg.event = EVENT_LCD_DEFAULT_EVT;
msg.param = param;
media_send_msg(&msg);
case EVENT_LCD_ROTATE_RIGHT_CMD:
//LOGI("EVENT_LCD_ROTATE_RIGHT_CMD \n");
lcd_act_rotate_degree90(param);
break;
}
}
#endif
#if CONFIG_MASTER_CORE
void mailbox_evt_handle(uint32_t event, uint32_t param)
{
switch (event)
{
case EVENT_LCD_DEFAULT_EVT:
LOGI("EVENT_LCD_DEFAULT_EVT \n");
param_pak_t *param_pak = (param_pak_t *)param;
LOGI("param: %08X\n", param_pak->param);
MEDIA_EVT_RETURN(param_pak, 0);
break;
#ifdef CONFIG_LCD
case EVENT_LCD_ROTATE_RIGHT_COMP_EVT:
//LOGI("EVENT_LCD_ROTATE_RIGHT_COMP_EVT\n");
lcd_act_rotate_complete((frame_buffer_t *)param);
break;
#endif
}
}
#endif
@@ -1,39 +0,0 @@
// Copyright (C) 2022 Beken Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <os/os.h>
#include <components/log.h>
#include "media_core.h"
#include "dvp_act.h"
#include "mailbox_channel.h"
static struct list_head media_mb_list;
void mailbox_queue_init(void)
{
INIT_LIST_HEAD(&media_mb_list);
}
void mailbox_queue_enqueue(void *param)
{
list_add_tail(param, &media_mb_list);
}
void mailbox_queue_dequeue(void *param)
{
list_add_tail(param, &media_mb_list);
}
@@ -1,336 +0,0 @@
// Copyright (C) 2022 Beken Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <os/os.h>
#include <components/log.h>
#include <stdio.h>
#include <driver/dma.h>
#include <driver/int.h>
#include <os/mem.h>
#include <driver/gpio.h>
#include <driver/gpio_types.h>
#include <driver/dma.h>
#include <driver/jpeg_enc.h>
#include <driver/jpeg_enc_types.h>
#include <driver/dvp_camera.h>
#include <driver/dvp_camera_types.h>
#include "frame_buffer.h"
#include "media_core.h"
#include "media_evt.h"
#include "storage_act.h"
#if (CONFIG_SDCARD_HOST)
#include "ff.h"
#include "diskio.h"
#endif
#define TAG "storage"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
static beken_queue_t storage_task_queue = NULL;
static beken_thread_t storage_task_thread = NULL;
typedef struct
{
uint8_t type;
uint32_t data;
} storages_task_msg_t;
typedef enum
{
STORAGE_TASK_DATA,
STORAGE_TASK_EXIT,
} storage_task_evt_t;
storage_info_t storage_info;
char *capture_name = NULL;
bk_err_t storage_task_send_msg(uint8_t msg_type, uint32_t data)
{
bk_err_t ret;
storages_task_msg_t msg;
if (storage_task_queue)
{
msg.type = msg_type;
msg.data = data;
ret = rtos_push_to_queue(&storage_task_queue, &msg, BEKEN_NO_WAIT);
if (kNoErr != ret)
{
os_printf("video_transfer_cpu1_send_msg failed\r\n");
return kOverrunErr;
}
return ret;
}
return kNoResourcesErr;
}
void storage_task_stop(void)
{
storage_task_send_msg(STORAGE_TASK_EXIT, 0);
while (storage_task_thread)
{
rtos_delay_milliseconds(10);
}
}
void storage_frame_buffer_dump(frame_buffer_t *frame, char *name)
{
LOGI("%s dump frame: %d, %p, %u, size: %d\n", __func__, frame->id, frame->frame, frame->sequence, frame->length);
#if (CONFIG_SDCARD_HOST)
FIL fp1;
unsigned int uiTemp = 0;
char file_name[50] = {0};
sprintf(file_name, "%d:/No.%d_%s", DISK_NUMBER_SDIO_SD, frame->sequence, name);
FRESULT fr = f_open(&fp1, file_name, FA_CREATE_ALWAYS | FA_WRITE);
if (fr != FR_OK)
{
LOGE("can not open file: %s, error: %d\n", file_name, fr);
return;
}
LOGI("open file:%s!\n", file_name);
fr = f_write(&fp1, (char *)frame->frame, frame->length, &uiTemp);
if (fr != FR_OK)
{
LOGE("f_write failed 1 fr = %d\r\n", fr);
}
f_close(&fp1);
LOGI("%s, complete\n", __func__);
#endif
}
static void storage_capture_save(frame_buffer_t *frame)
{
media_msg_t msg;
LOGI("%s save frame: %d, size: %d", __func__, frame->id, frame->length);
#if (CONFIG_SDCARD_HOST)
FIL fp1;
unsigned int uiTemp = 0;
char file_name[50] = {0};
sprintf(file_name, "%d:/%s", DISK_NUMBER_SDIO_SD, capture_name);
FRESULT fr = f_open(&fp1, file_name, FA_CREATE_ALWAYS | FA_WRITE);
if (fr != FR_OK)
{
LOGE("can not open file: %s, error: %d\n", file_name, fr);
goto error;
}
LOGI("open file:%s!\n", file_name);
fr = f_write(&fp1, (char *)frame->frame, frame->length, &uiTemp);
if (fr != FR_OK)
{
LOGE("f_write failed 1 fr = %d\r\n", fr);
}
f_close(&fp1);
LOGI("%s, complete\n", __func__);
error:
#endif
msg.event = EVENT_COM_FRAME_CAPTURE_FREE_IND;
msg.param = (uint32_t)frame;
media_send_msg(&msg);
storage_info.capture_state = STORAGE_STATE_DISABLED;
}
static void storage_task_entry(beken_thread_arg_t data)
{
bk_err_t ret = BK_OK;
storages_task_msg_t msg;
while (1)
{
ret = rtos_pop_from_queue(&storage_task_queue, &msg, BEKEN_WAIT_FOREVER);
if (kNoErr == ret)
{
switch (msg.type)
{
case STORAGE_TASK_DATA:
storage_capture_save((frame_buffer_t *)msg.data);
break;
case STORAGE_TASK_EXIT:
goto exit;
default:
break;
}
}
}
exit:
rtos_deinit_queue(&storage_task_queue);
storage_task_queue = NULL;
storage_task_thread = NULL;
rtos_delete_thread(NULL);
}
int storage_task_start(void)
{
int ret;
if (storage_task_queue == NULL)
{
ret = rtos_init_queue(&storage_task_queue, "trs_task_queue", sizeof(storages_task_msg_t), 60);
if (kNoErr != ret)
{
LOGE("%s trs_task_queue init failed\n");
goto error;
}
}
if (storage_task_thread == NULL)
{
ret = rtos_create_thread(&storage_task_thread,
4,
"storage_task_thread",
(beken_thread_function_t)storage_task_entry,
4 * 1024,
NULL);
if (kNoErr != ret)
{
LOGE("%s trs_task_thread init failed\n");
goto error;
}
}
return kNoErr;
error:
if (storage_task_queue)
{
rtos_deinit_queue(&storage_task_queue);
storage_task_queue = NULL;
}
if (storage_task_thread)
{
storage_task_thread = NULL;
rtos_delete_thread(NULL);
}
return kGeneralErr;
}
void storage_open_handle(void)
{
LOGI("%s\n", __func__);
LOGI("%s register camera init\n", __func__);
}
void storage_capture_frame_callback(frame_buffer_t *frame)
{
storage_task_send_msg(STORAGE_TASK_DATA, (uint32_t)frame);
}
void storage_capture_handle(param_pak_t *param)
{
LOGI("%s, %s\n", __func__, (char *)param->param);
if (storage_info.capture_state == STORAGE_STATE_ENABLED)
{
LOGI("%s already capture\n", __func__);
goto out;
}
if (capture_name == NULL)
{
capture_name = (char *)os_malloc(32);
}
os_memcpy(capture_name, (char *)param->param, 31);
capture_name[31] = 0;
frame_buffer_frame_register(MODULE_CAPTURE, storage_capture_frame_callback);
storage_info.capture_state = STORAGE_STATE_ENABLED;
out:
MEDIA_EVT_RETURN(param, kNoErr);
}
void storage_event_handle(uint32_t event, uint32_t param)
{
switch (event)
{
case EVENT_STORAGE_OPEN_IND:
storage_open_handle();
break;
case EVENT_STORAGE_CAPTURE_IND:
storage_capture_handle((param_pak_t *)param);
break;
}
}
storage_state_t get_storage_state(void)
{
return storage_info.state;
}
void set_storage_state(storage_state_t state)
{
storage_info.state = state;
}
void storage_init(void)
{
os_memset(&storage_info, 0, sizeof(storage_info_t));
storage_info.state = STORAGE_STATE_DISABLED;
storage_info.capture_state = STORAGE_STATE_DISABLED;
storage_task_start();
}
@@ -1,539 +0,0 @@
// Copyright (C) 2022 Beken Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <os/os.h>
#include <components/log.h>
#include <components/video_transfer.h>
#include "media_core.h"
#include <driver/int.h>
#include <os/mem.h>
#include <driver/gpio.h>
#include <driver/gpio_types.h>
#include <driver/dma.h>
#include <os/mem.h>
#include <driver/gpio.h>
#include <driver/gpio_types.h>
#include <driver/dma.h>
#include <driver/i2c.h>
#include <driver/jpeg_enc.h>
#include <driver/jpeg_enc_types.h>
#include <driver/uvc_camera.h>
#include <driver/dvp_camera.h>
#include <driver/dvp_camera_types.h>
#include <driver/media_types.h>
#include <soc/mapping.h>
#include <driver/timer.h>
#include "bk_general_dma.h"
#include "transfer_act.h"
#include "media_evt.h"
#include "frame_buffer.h"
#include "wlan_ui_pub.h"
#include "bk_misc.h"
#define TAG "transfer"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
typedef struct
{
uint8_t type;
uint32_t data;
} trs_task_msg_t;
typedef enum
{
TRS_TRANSFER_DATA,
TRS_TRANSFER_EXIT,
} trs_task_msg_type_t;
typedef struct
{
uint8_t id;
uint8_t eof;
uint8_t cnt;
uint8_t size;
uint8_t data[];
} transfer_data_t;
transfer_info_t transfer_info;
#define MAX_TX_SIZE (1472)
#define MAX_COPY_SIZE (1472 - sizeof(transfer_data_t))
#define MAX_RETRY (10000)
#define RETRANSMITS_TIME (5)
static beken_queue_t trs_task_queue = NULL;
static beken_thread_t trs_task_thread = NULL;
extern media_debug_t *media_debug;
transfer_data_t *wifi_tranfer_data = NULL;
uint8_t frame_id = 0;
bool runing = false;
frame_buffer_t *wifi_tranfer_frame = NULL;
video_setup_t vido_transfer_info = {0};
uint32_t lost_size = 0;
uint32_t complete_size = 0;
uint32_t transfer_timer_us = 0; // unit us
extern void rwnxl_set_video_transfer_flag(uint32_t video_transfer_flag);
int dvp_frame_send(uint8_t *data, uint32_t size, uint32_t retry_max, uint32_t ms_time, uint32_t us_delay_time)
{
int ret = BK_FAIL;
if (!vido_transfer_info.send_func)
{
return ret;
}
do
{
ret = vido_transfer_info.send_func(data, size);
if (ret == size)
{
//LOGI("size: %d\n", size);
complete_size += size;
delay_us(us_delay_time);
break;
}
//LOGI("retry\n");
lost_size += size;
rtos_delay_milliseconds(ms_time);
}
while (retry_max-- && runing);
return ret == size ? BK_OK : BK_FAIL;
}
static void dvp_frame_handle(frame_buffer_t *buffer)
{
uint32_t i;
uint32_t count = buffer->length / MAX_COPY_SIZE;
uint32_t tail = buffer->length % MAX_COPY_SIZE;
uint8_t id = frame_id++;
int ret;
uint32_t delay_time = (transfer_timer_us / (count + 1));
if (delay_time > 500)
delay_time -= 500;
LOGD("id: %u, seq: %u, length: %u, size: %u\n", buffer->id, buffer->sequence, buffer->length, buffer->size);
wifi_tranfer_data->id = id;
wifi_tranfer_data->size = 0;
wifi_tranfer_data->eof = 0;
wifi_tranfer_data->cnt = 0;
for (i = 0; i < count && runing; i++)
{
if ((tail == 0) && (i == count - 1))
{
wifi_tranfer_data->eof = 1;
wifi_tranfer_data->cnt = count;
}
dma_memcpy(wifi_tranfer_data->data, buffer->frame + (MAX_COPY_SIZE * i), MAX_COPY_SIZE);
ret = dvp_frame_send((uint8_t *)wifi_tranfer_data, MAX_TX_SIZE, MAX_RETRY, RETRANSMITS_TIME, delay_time);
if (ret != BK_OK)
{
LOGE("send failed\n");
}
}
if (tail)
{
wifi_tranfer_data->eof = 1;
wifi_tranfer_data->cnt = count + 1;
/* fix for psram 4bytes alignment */
dma_memcpy(wifi_tranfer_data->data, buffer->frame + (MAX_COPY_SIZE * i), (tail % 4) ? ((tail / 4 + 1) * 4) : tail);
ret = dvp_frame_send((uint8_t *)wifi_tranfer_data, tail + sizeof(transfer_data_t), MAX_RETRY, RETRANSMITS_TIME, delay_time);
if (ret != BK_OK)
{
LOGE("send failed\n");
}
}
media_debug->fps_wifi++;
LOGD("seq: %u, length: %u, tail: %u, count: %u\n", id, buffer->length, tail, count);
if (wifi_tranfer_frame)
{
media_msg_t msg;
msg.event = EVENT_COM_FRAME_WIFI_FREE_IND;
msg.param = (uint32_t)buffer;
media_send_msg(&msg);
wifi_tranfer_frame = NULL;
}
}
void transfer_dump(uint32_t ms)
{
uint32_t lost = lost_size, complete = complete_size, speed;
lost_size = 0;
complete_size = 0;
if (transfer_info.state == TRS_STATE_DISABLED)
{
return;
}
lost = lost / 1024 / (ms / 1000);
complete = complete / 1024 / (ms / 1000);
speed = (complete * 8) / 1024;
LOGI("Lost: %uKB/s, Complete: %uKB/s, Speed: %uMb/s\n", lost, complete, speed);
}
static void trs_task_entry(beken_thread_arg_t data)
{
bk_err_t ret = BK_OK;
trs_task_msg_t msg;
dvp_camera_device_t *dvp_device = NULL;
dvp_device = bk_dvp_camera_get_device();
if (dvp_device == NULL || dvp_device->id == ID_UNKNOW)
{
LOGE("dvp camera was not init\n");
#if (CONFIG_USB_UVC)
uvc_camera_device_t *uvc_device = NULL;
uvc_device = bk_uvc_camera_get_device();
if (uvc_device == NULL)
{
LOGE("uvc camera was not init\n");
goto exit;
}
transfer_timer_us = 1000 * 1000 / uvc_device->fps; //us
LOGI("transfer_timer_us: %d, fps:%d\r\n", transfer_timer_us, uvc_device->fps);
#else
goto exit;
#endif
}
else
{
uint32_t fps = 20;
switch (dvp_device->fps)
{
case FPS5:
fps = 5;
break;
case FPS10:
fps = 10;
break;
case FPS15:
fps = 15;
break;
case FPS20:
fps = 20;
break;
case FPS25:
fps = 25;
break;
case FPS30:
fps = 30;
break;
}
transfer_timer_us = 1000 * 1000 / fps - 1000;//us
LOGI("transfer_timer_us: %d, fps:%d\r\n", transfer_timer_us, fps);
}
while (1)
{
ret = rtos_pop_from_queue(&trs_task_queue, &msg, BEKEN_WAIT_FOREVER);
if (BK_OK == ret)
{
switch (msg.type)
{
case TRS_TRANSFER_DATA:
if (false == frame_buffer_get_state() && runing)
{
break;
}
dvp_frame_handle((frame_buffer_t *)msg.data);
break;
case TRS_TRANSFER_EXIT:
goto exit;
default:
break;
}
}
}
exit:
if (wifi_tranfer_data != NULL)
{
os_free(wifi_tranfer_data);
wifi_tranfer_data = NULL;
}
frame_id = 0;
rtos_deinit_queue(&trs_task_queue);
trs_task_queue = NULL;
trs_task_thread = NULL;
rtos_delete_thread(NULL);
}
int transfer_task_start(video_setup_t *setup_cfg)
{
int ret;
os_memcpy(&vido_transfer_info, setup_cfg, sizeof(video_setup_t));
media_debug->fps_wifi = 0;
runing = true;
if (wifi_tranfer_data == NULL)
{
wifi_tranfer_data = (transfer_data_t *) os_malloc(MAX_TX_SIZE);
}
frame_id = 0;
if (trs_task_queue == NULL)
{
ret = rtos_init_queue(&trs_task_queue, "trs_task_queue", sizeof(trs_task_msg_t), 60);
if (BK_OK != ret)
{
LOGE("%s trs_task_queue init failed\n");
goto error;
}
}
if (trs_task_thread == NULL)
{
ret = rtos_create_thread(&trs_task_thread,
4,
"trs_task_thread",
(beken_thread_function_t)trs_task_entry,
4 * 1024,
NULL);
if (BK_OK != ret)
{
LOGE("%s trs_task_thread init failed\n");
goto error;
}
}
return BK_OK;
error:
if (wifi_tranfer_frame)
{
media_msg_t msg;
msg.event = EVENT_COM_FRAME_WIFI_FREE_IND;
msg.param = (uint32_t)wifi_tranfer_frame;
media_send_msg(&msg);
wifi_tranfer_frame = NULL;
}
if (trs_task_queue)
{
rtos_deinit_queue(&trs_task_queue);
trs_task_queue = NULL;
}
if (trs_task_thread)
{
trs_task_queue = NULL;
rtos_delete_thread(NULL);
}
return BK_FAIL;
}
bk_err_t transfer_task_send_msg(uint8_t msg_type, uint32_t data)
{
bk_err_t ret;
trs_task_msg_t msg;
if (trs_task_queue)
{
msg.type = msg_type;
msg.data = data;
ret = rtos_push_to_queue(&trs_task_queue, &msg, BEKEN_NO_WAIT);
if (BK_OK != ret)
{
LOGE("video_transfer_cpu1_send_msg failed\r\n");
return BK_FAIL;
}
return ret;
}
return kNoResourcesErr;
}
void transfer_task_stop(void)
{
runing = false;
transfer_task_send_msg(TRS_TRANSFER_EXIT, 0);
while (trs_task_thread)
{
rtos_delay_milliseconds(10);
}
}
frame_buffer_t *get_wifi_transfer_frame(void)
{
return wifi_tranfer_frame;
}
void transfer_frame_complete_callback(frame_buffer_t *buffer)
{
LOGD("%s\n", __func__);
wifi_tranfer_frame = buffer;
if (transfer_info.pause)
{
frame_buffer_free_request(buffer, MODULE_WIFI);
return;
}
transfer_task_send_msg(TRS_TRANSFER_DATA, (uint32_t)buffer);
}
void transfer_open_handle(param_pak_t *param)
{
video_setup_t *setup_cfg = (video_setup_t *)param->param;
LOGI("%s ++\n", __func__);
frame_buffer_frame_register(MODULE_WIFI, transfer_frame_complete_callback);
transfer_task_start(setup_cfg);
set_transfer_state(TRS_STATE_ENABLED);
MEDIA_EVT_RETURN(param, BK_OK);
LOGI("%s --\n", __func__);
}
void transfer_close_handle(param_pak_t *param)
{
LOGI("%s\n", __func__);
wifi_tranfer_frame = NULL;
transfer_task_stop();
set_transfer_state(TRS_STATE_DISABLED);
frame_buffer_frame_deregister(MODULE_WIFI);
rwnxl_set_video_transfer_flag(false);
bk_wlan_ps_enable();
MEDIA_EVT_RETURN(param, BK_OK);
}
void transfer_pause_handle(param_pak_t *param)
{
LOGI("%s, %d\n", __func__, param->param);
GLOBAL_INT_DECLARATION();
GLOBAL_INT_DISABLE();
transfer_info.pause = param->param;
GLOBAL_INT_RESTORE();
MEDIA_EVT_RETURN(param, BK_OK);
}
void transfer_event_handle(uint32_t event, uint32_t param)
{
switch (event)
{
case EVENT_TRANSFER_OPEN_IND:
transfer_open_handle((param_pak_t *)param);
break;
case EVENT_TRANSFER_CLOSE_IND:
transfer_close_handle((param_pak_t *)param);
break;
case EVENT_TRANSFER_PAUSE_IND:
transfer_pause_handle((param_pak_t *)param);
break;
}
}
trs_state_t get_transfer_state(void)
{
return transfer_info.state;
}
void set_transfer_state(trs_state_t state)
{
transfer_info.state = state;
}
void transfer_init(void)
{
transfer_info.state = TRS_STATE_DISABLED;
transfer_info.debug = false;
transfer_info.pause = false;
}

Some files were not shown because too many files have changed in this diff Show More