typedef enum {
SEA_OUTPUT_REC_SRC = 0, /* Output source for recording */
SEA_OUTPUT_ASR_SRC, /* Output source for Voice Kit APP */
- SEA_OUTPUT_VC_SRC, /* Output source for Voice Call APP */
+ SEA_OUTPUT_VC_SRC, /* Output source for Call APP */
SEA_OUTPUT_AH_SRC, /* Output source for AH output */
SEA_OUTPUT_KWS_SRC, /* Output source for Keyword Engine */
SEA_OUTPUT_MAX
set(COMPONENT_NAME "batterry_service")
set(PUBLIC_HEADER
-${CMAKE_CURRENT_SOURCE_DIR}
+${CMAKE_CURRENT_SOURCE_DIR}/hal
+${CMAKE_CURRENT_SOURCE_DIR}/test
+)
+set(PRIVATE_HEADER
+${CMAKE_CURRENT_SOURCE_DIR}/service
)
set(SOURCES
-${CMAKE_CURRENT_SOURCE_DIR}/battery.c
-${CMAKE_CURRENT_SOURCE_DIR}/battery_at_cmd.c
+${CMAKE_CURRENT_SOURCE_DIR}/service/battery_service.c
+${CMAKE_CURRENT_SOURCE_DIR}/test/battery_at_cmd.c
+${CMAKE_CURRENT_SOURCE_DIR}/hal/battery_hal.c
)
set(COMPONENT_PUBLIC_CCFLAGS
+++ /dev/null
-/**
- * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n
- *
- * Description: Test adc source \n
- * Author: @CompanyNameTag \n
- * History: \n
- * 2022-08-16, Create file. \n
- */
-
-#include "adc.h"
-#define TEST_PARAM_ARGC_1 1
-#define TEST_PARAM_ARGC_2 2
-#define TEST_PARAM_ARGC_3 3
-#define TEST_PARAM_ARGC_4 4
-#define TEST_PARAM_ARGC_5 5
-#define TEST_PARAM_ARGC_6 6
-#define TEST_PARAM_ARGC_7 7
-#define TEST_PARAM_4_BYTES 4
-#define TEST_PARAM_8_BYTES 8
-typedef enum {
- SUITE_OK = 0,
- SUITE_UNKNOWN_FUNCTION = -1,
- SUITE_ERROR_TIMED_OUT = -2,
- SUITE_ERROR_BAD_PARAMS = -3,
- SUITE_ERROR_PIN_ALLOCATION = -4,
- SUITE_ERROR_PIN_DEALLOCATION = -5,
- SUITE_ERROR_UNEXPECTED_INTERRUPT = -6,
- SUITE_ALLOC_FAILED = -7,
- SUITE_CONFIG_FAILED = -8,
- SUITE_TEST_FAILED = -254,
-} battery_error_e;
-
-#if defined(CONFIG_ADC_SUPPORT_AFE)
-
-#error CONFIG_ADC_SUPPORT_AFE
-
-#include "hal_adc_v152.h"
-#include "hal_adc_v152_regs_op.h"
-#else
-#include "hal_adc_v151.h"
-#include "hal_adc_v151_regs_op.h"
-#endif
-#include "adc_porting.h"
-
-#include "pinctrl.h"
-
-#include "debug_print.h"
-#include "soc_osal.h"
-#include "tcxo.h"
-#include "irmalloc.h"
-#include "errcode.h"
-#include "common_def.h"
-
-#include "battery.h"
-
-#if defined(CONFIG_ADC_SUPPORT_AFE)
-
-
-#define ADC_AUTO_SAMPLE_TEST_TIMES 1000
-#define HADC_DEFAULT_CALI \
-{ \
- .hadc_os_code = 0x68, \
- .hadc_wt_b22 = 0x75fdd, \
- .hadc_wt_b21 = 0x3ef67, \
- .hadc_wt_b20 = 0x1f7ae, \
- .hadc_wt_b19 = 0xfc3d, \
- .hadc_wt_b18 = 0x7e22, \
- .hadc_wt_b17 = 0x7dc9, \
- .hadc_wt_b16 = 0x3f01, \
- .hadc_wt_b15 = 0x1f80, \
- .hadc_wt_b14 = 0xfc5, \
- .hadc_wt_b13 = 0x800, \
- .hadc_wt_b12 = 0x800, \
- .hadc_wt_b11 = 0x400, \
- .hadc_wt_b10 = 0x200, \
- .hadc_wt_b9 = 0x100, \
- .dac_code1 = 0x200, \
- .dac_code2 = 0x1d5, \
-}
-
-afe_config_t g_afe_config = HADC_DEFAULT_CALI;
-static bool g_afe_open_flag = false;
-
-static int gadc_open_test(int argc, char *argv[])
-{
- if (argc < 1) {
- return SUITE_ERROR_BAD_PARAMS;
- }
- adc_v152_gadc_channel_sel_t gadc_channel = (adc_v152_gadc_channel_sel_t)strtol(argv[0], NULL, 0);
- if (gadc_channel > SINGLE_END_AINN4) {
- return SUITE_ERROR_BAD_PARAMS;
- }
- errcode_t ret = uapi_adc_init(ADC_CLOCK_NONE);
- if (ret != ERRCODE_SUCC) {
- return ret;
- }
- uapi_adc_open_channel(gadc_channel);
- uapi_adc_power_en(AFE_GADC_MODE, true);
- adc_calibration(AFE_GADC_MODE, true, false, false);
- hadc_gain_set(PGA_GAIN_EIGHT, IA_GAIN_SIXTEEN);
- uapi_adc_manual_sample((adc_channel_t)AFE_GADC_MODE);
- g_afe_open_flag = true;
- return SUITE_OK;
-}
-
-static int hadc_open_test(int argc, char *argv[])
-{
- UNUSED(argc);
- UNUSED(argv);
- bool cali_en = (bool)strtol(argv[0], NULL, 0);
- errcode_t ret = uapi_adc_init(ADC_CLOCK_NONE);
- if (ret != ERRCODE_SUCC) {
- return ret;
- }
- uapi_adc_power_en(AFE_HADC_MODE, true);
- if (cali_en) {
- adc_calibration(AFE_HADC_MODE, true, true, true);
- g_afe_config.hadc_os_code = reg32(0x57036244); // hadc_os_code
- g_afe_config.hadc_wt_b22 = reg32(0x570361B0); // hadc_wt_b22
- g_afe_config.hadc_wt_b21 = reg32(0x570361B4); // hadc_wt_b21
- g_afe_config.hadc_wt_b20 = reg32(0x570361B8); // hadc_wt_b20
- g_afe_config.hadc_wt_b19 = reg32(0x570361BC); // hadc_wt_b19
- g_afe_config.hadc_wt_b18 = reg32(0x570361C0); // hadc_wt_b18
- g_afe_config.hadc_wt_b17 = reg32(0x570361C4); // hadc_wt_b17
- g_afe_config.hadc_wt_b16 = reg32(0x570361C8); // hadc_wt_b16
- g_afe_config.hadc_wt_b15 = reg32(0x570361CC); // hadc_wt_b15
- g_afe_config.hadc_wt_b14 = reg32(0x570361D0); // hadc_wt_b14
- g_afe_config.hadc_wt_b13 = reg32(0x570361D4); // hadc_wt_b13
- g_afe_config.hadc_wt_b12 = reg32(0x570361D8); // hadc_wt_b12
- g_afe_config.hadc_wt_b11 = reg32(0x570361DC); // hadc_wt_b11
- g_afe_config.hadc_wt_b10 = reg32(0x570361E0); // hadc_wt_b10
- g_afe_config.hadc_wt_b9 = reg32(0x570361E4); // hadc_wt_b9
- g_afe_config.dac_code1 = reg32(0x570363D4); // dac_code1
- g_afe_config.dac_code2 = reg32(0x570363D8); // dac_code2
- } else {
- afe_config_t afe_config = g_afe_config;
- adc_set_cali_code(AFE_HADC_MODE, &afe_config);
- }
- uapi_adc_manual_sample(HADC_CHANNEL_0);
- g_afe_open_flag = true;
- return SUITE_OK;
-}
-
-static int adc_auto_sample_test(int argc, char *argv[])
-{
- if (argc < 1) {
- return SUITE_ERROR_BAD_PARAMS;
- }
- if (!g_afe_open_flag) {
- return SUITE_TEST_FAILED;
- }
- adc_v152_gadc_channel_sel_t channel = (adc_v152_gadc_channel_sel_t)strtol(argv[0], NULL, 0);
- uapi_adc_open_channel(channel);
- int adc_value = 0;
- adc_channel_t ch = channel <= SINGLE_END_AINN4 ? (adc_channel_t)AFE_GADC_MODE : HADC_CHANNEL_0;
- uint32_t irq_sts = osal_irq_lock();
- for (int i = 0; i < ADC_AUTO_SAMPLE_TEST_TIMES; i++) {
- adc_value = uapi_adc_auto_sample(ch);
- suite_log_stringf("adc: 0x%x = %d\n", adc_value, adc_value);
- }
- UNUSED(adc_value);
- osal_irq_restore(irq_sts);
- return SUITE_OK;
-}
-
-static int hadc_power_on(int argc, char *argv[])
-{
- UNUSED(argc);
- UNUSED(argv);
- uapi_adc_power_en(AFE_HADC_MODE, true);
- adc_set_cali_code(AFE_HADC_MODE, &g_afe_config);
- return SUITE_OK;
-}
-
-static int hadc_power_off(int argc, char *argv[])
-{
- UNUSED(argc);
- UNUSED(argv);
- uapi_adc_power_en(AFE_HADC_MODE, false);
- return SUITE_OK;
-}
-
-#else
-#define HAL_ADC_SAMPLE_NUMBER_CONFIG_0 10 /* Channel with buffer manual sample average number. */
-#define HAL_ADC_SAMPLE_NUMBER_CONFIG_1 10 /* Channel without buffer manual sample average number. */
-#define HAL_ADC_DISCARD_NUMBER_CONFIG_0 8 /* Channel with buffer manual sample discard number. */
-#define HAL_ADC_DISCARD_NUMBER_CONFIG_1 8 /* Channel without buffer manual sample discard number. */
-
-#define adc_trans_sytick_to_voltage(x) ((float)(((float)(x) * 17) / 40960))
-#define adc_trans_sytick_to_voltage_diff(x) ((float)(((float)((x) - 2048) * 17) / 20480))
-// #define adc_trans_sytick_to_voltage_without_auto_scan(x) ((float)(((float)(x) * 18) / 40960))
-#define adc_trans_sytick_to_voltage_without_auto_scan(x) ((float)(((float)(x) * 18) / 40960))
-
-static uint32_t g_adc_sample_times = 0;
-static uint32_t g_adc_sample_discard = 0;
-static uint32_t g_adc_sample_stick = 0;
-
-#define TESTADC_DISACRD_DELAY_MS 3
-#define MINIMUM_VOLTAGE_RANGE 2
-#define MAXIMUM_VOLTAGE_RANGE 17
-
-static uint32_t adc_get_sample_times(void)
-{
- return g_adc_sample_times;
-}
-
-static uint32_t adc_get_sample_discard(void)
-{
- return g_adc_sample_discard;
-}
-
-static void adc_set_sample_stick(uint32_t stick)
-{
- g_adc_sample_stick = stick;
-}
-
-static uint32_t adc_get_sample_stick(void)
-{
- return g_adc_sample_stick;
-}
-
-static float adc_stick_transfer_voltage(uint16_t stick, adc_channel_t channel)
-{
-#if defined(CONFIG_ADC_SUPPORT_AUTO_SCAN)
- hal_adc_type_info_t *adc_cfg_info = NULL;
- adc_cfg_info = adc_port_get_cfg();
- /* diff channel: (stick - 2048)/ 2048 * 1.8 ; */
- if (adc_cfg_info != NULL && adc_cfg_info[channel].channel_type == HAL_ADC_CHANNEL_TYPE_DIF_BUF) {
- return adc_trans_sytick_to_voltage_diff(stick);
- } else {
- return adc_trans_sytick_to_voltage(stick);
- }
-#else
- UNUSED(channel);
- return adc_trans_sytick_to_voltage_without_auto_scan(stick);
-#endif
-}
-
-static bool adc_get_sample_result(float *voltage, uint8_t channel)
-{
- uint32_t sample_number = 0;
- uint32_t discard_number = 0;
- uint32_t stick = 0;
- uint32_t sample_zero_count = 0;
-
-#if defined(CONFIG_ADC_SUPPORT_AUTO_SCAN)
- if (uapi_adc_auto_scan_is_enabled()) { return false; }
-#endif /* CONFIG_ADC_SUPPORT_AUTO_SCAN */
-
- if (channel >= ADC_CHANNEL_4) {
- sample_number = HAL_ADC_SAMPLE_NUMBER_CONFIG_1;
- discard_number = HAL_ADC_DISCARD_NUMBER_CONFIG_1;
- } else {
- sample_number = HAL_ADC_SAMPLE_NUMBER_CONFIG_0;
- discard_number = HAL_ADC_DISCARD_NUMBER_CONFIG_0;
- }
-
- if (g_adc_sample_times != 0) {
- sample_number = adc_get_sample_times();
- }
-
- if (g_adc_sample_discard != 0) {
- discard_number = adc_get_sample_discard();
- }
-
- /* after channel is enabled, sample result is error in previous samplings, need to be discarded */
- for (uint32_t i = 0; i < discard_number; i++) {
- uapi_adc_manual_sample(ADC_CHANNEL_NONE);
- uapi_tcxo_delay_ms((uint64_t)TESTADC_DISACRD_DELAY_MS);
- }
-
- for (uint32_t i = 0; i < sample_number; i++) {
- uint32_t irq_sts = osal_irq_lock();
- uint32_t sample_result = (uint32_t)uapi_adc_manual_sample(ADC_CHANNEL_NONE);
- osal_printk("sample_result = %d.\r\n", sample_result);
- if (sample_result == 0) { sample_zero_count++; }
- stick += sample_result;
- osal_irq_restore(irq_sts);
- }
- sample_number -= sample_zero_count;
- if (sample_number > 0) {
- stick = (stick / sample_number);
- } else {
- *voltage = 0;
- return false;
- }
-
- adc_set_sample_stick(stick);
- *voltage = adc_stick_transfer_voltage((uint16_t)stick, channel);
-
- UNUSED(discard_number);
- return true;
-}
-
-/**
- * @brief Get voltage by the channel. Available voltage rang is 0V ~ 1.7V.
- * @param voltage The sample result of voltage.
- * @param channel The adc channel.
- * @return true when select channel success, false when seclect channel failed.
- */
-static bool adc_get_voltage_by_channel(float *voltage, uint8_t channel)
-{
- bool ret = false;
-
- uapi_adc_power_en(AFE_SCAN_MODE_MAX_NUM, true);
- ret = uapi_adc_open_channel(channel);
- if (ret == ERRCODE_SUCC) {
- ret = adc_get_sample_result(voltage, channel);
- if (ret) {
- uapi_adc_close_channel(channel);
- uapi_adc_power_en(AFE_SCAN_MODE_MAX_NUM, false);
- return true;
- }
- } else {
- osal_printk("uapi_adc_open_channel failed : %d\r\n", ret);
- }
-
- *voltage = 0;
- uapi_adc_close_channel(channel);
- uapi_adc_power_en(AFE_SCAN_MODE_MAX_NUM, false);
- return false;
-}
-
-
-
-#if defined(CONFIG_ADC_SUPPORT_AUTO_SCAN)
-static bool g_adc_scan_continue = false;
-static void adc_callback(uint8_t ch, uint32_t *buffer, uint32_t length, bool *next)
-{
- osal_printk("[IRQ]channel: %d, buffer:0x%x, len: %d. \r\n", ch, buffer, length);
- uint64_t data = 0;
-#if defined(CONFIG_ADC_SUPPORT_LONG_SAMPLE)
- osal_printk("sample data head: %d %d %d %d\r\n", buffer[0], buffer[TEST_PARAM_ARGC_1],
- buffer[TEST_PARAM_ARGC_2], buffer[TEST_PARAM_ARGC_3]);
- osal_printk("sample data tail: %d %d %d %d\r\n", buffer[length - TEST_PARAM_ARGC_4],
- buffer[length - TEST_PARAM_ARGC_3], buffer[length - TEST_PARAM_ARGC_2], buffer[length - TEST_PARAM_ARGC_1]);
-#else
- for (uint32_t i = 0; i < length; i++) {
- osal_printk("[%d]data: %d\r\n", i, buffer[i]);
- data += buffer[i];
- }
-
- if (length != 0) {
- data = data / length;
- }
- osal_printk("average data: %d\r\n", (uint32_t)data);
-#endif
- *next = g_adc_scan_continue;
- UNUSED(ch);
- UNUSED(buffer);
- UNUSED(length);
- UNUSED(next);
-}
-
-static int adc_stop_auto_scan(int argc, char *argv[])
-{
- adc_channel_t channel;
- if (argc != 1) { /* 1: Indicates the number of input parameters */
- return SUITE_ERROR_BAD_PARAMS;
- }
- channel = (adc_channel_t)strtol(argv[0], NULL, 0);
- if (uapi_adc_auto_scan_ch_disable((uint8_t)channel) == ERRCODE_SUCC) {
- return SUITE_OK;
- } else {
- return SUITE_TEST_FAILED;
- }
-}
-
-static int adc_start_auto_scan(int argc, char *argv[])
-{
- pin_t pin;
- pin_mode_t mode;
-#if defined(CONFIG_ADC_SUPPORT_LONG_SAMPLE)
- if (argc != 7) { /* 7: Indicates the number of input parameters */
- return SUITE_ERROR_BAD_PARAMS;
- }
-#else
- if (argc != 6) { /* 6: Indicates the number of input parameters */
- return SUITE_ERROR_BAD_PARAMS;
- }
-#endif
- adc_channel_t channel;
- channel = (adc_channel_t)strtol(argv[0], NULL, 0);
- g_adc_scan_continue = (bool)strtol(argv[TEST_PARAM_ARGC_1], NULL, 0);
- pin = (pin_t)strtol(argv[TEST_PARAM_ARGC_2], NULL, 0);
- mode = (pin_mode_t)strtol(argv[TEST_PARAM_ARGC_3], NULL, 0);
- adc_scan_config_t config = {
- .type = (uint8_t)strtol(argv[TEST_PARAM_ARGC_4], NULL, 0),
- .threshold_l = 0.5, /* 0.5: Threshold scan volatage(v) lower limit. */
- .threshold_h = 1.5, /* 1.5: Threshold scan volatage(v) upper limit. */
- .freq = (uint8_t)strtol(argv[TEST_PARAM_ARGC_5], NULL, 0),
-#if defined(CONFIG_ADC_SUPPORT_LONG_SAMPLE)
- .long_sample_time = (uint32_t)strtol(argv[TEST_PARAM_ARGC_6], NULL, 0),
-#endif
- };
- osal_printk("chan: %d, freq: %d\r\n", channel, config.freq);
-#if defined(CONFIG_ADC_SUPPORT_LONG_SAMPLE)
- osal_printk("long_sample_time = %d\n", config.long_sample_time);
-#endif
-
- uapi_pin_set_mode(pin, mode);
- uapi_adc_power_en(AFE_SCAN_MODE_MAX_NUM, true);
- if (uapi_adc_auto_scan_ch_enable((uint8_t)channel, config, adc_callback) == ERRCODE_SUCC) {
- return SUITE_OK;
- } else {
- return SUITE_TEST_FAILED;
- }
-}
-#endif /* CONFIG_ADC_SUPPORT_AUTO_SCAN */
-#endif /* CONFIG_ADC_SUPPORT_AFE */
-bool battery_get_voltage_by_channel(float *voltage, uint8_t channel)
-{
-
-#if defined(CONFIG_ADC_SUPPORT_AFE)
- // uapi_suite_add_function("gadc_open_test", "GAFE init & enable test <Sample end: 0~7>", gadc_open_test);
- // uapi_suite_add_function("hadc_open_test", "HAFE init & enable test <Cali enable>", hadc_open_test);
- // uapi_suite_add_function("auto_sample_test", "AFE auto sample test Params: <Sample end: GAFE:0~7 HAFE:8>",
- // adc_auto_sample_test);
- // uapi_suite_add_function("hadc_power_off", "HAFE low power test, power off hafe", hadc_power_off);
- // uapi_suite_add_function("hadc_power_on", "HAFE low power test, power on hafe ", hadc_power_on);
-#else
- uapi_adc_init(ADC_CLOCK_500KHZ);
- // uapi_adc_power_en(AFE_SCAN_MODE_MAX_NUM, true);
- // uapi_suite_add_function("adc_manual_test", "Params: <Channel>, <sample_times>, <discard_times>,"
- // "<pin number>, <pin mode>", adc_manual_test);
- // adc_channel_t channel;
-
- uint64_t time1, time2;
- uint32_t param_index = 0;
- // channel = (adc_channel_t)strtol(argv[param_index++], NULL, 0);
- // g_adc_sample_times = (uint32_t)strtol(argv[param_index++], NULL, 0);
- // g_adc_sample_discard = (uint32_t)strtol(argv[param_index++], NULL, 0);
- // pin = (pin_t)strtol(argv[param_index++], NULL, 0);
- // mode = (pin_mode_t)strtol(argv[param_index++], NULL, 0);
- osal_printk("channel: %d, sample times: %d, discard: %d.\r\n", channel, g_adc_sample_times, g_adc_sample_discard);
-
- // uapi_pin_set_mode(pin, mode);
-#if defined(CONFIG_ADC_SUPPORT_AUTO_SCAN)
- uapi_adc_auto_scan_disable();
-#endif /* CONFIG_ADC_SUPPORT_AUTO_SCAN */
- // osal_printk("PINMUX SET DONE\r\n");
-
- time1 = uapi_tcxo_get_us();
-
- if (!adc_get_voltage_by_channel(voltage, channel)) {
- osal_printk("adc get sample result failed.\r\n");
- return SUITE_TEST_FAILED;
- }
- time2 = uapi_tcxo_get_us();
-
- osal_printk("tick: %d, Sample time: %d. \r\n", adc_get_sample_stick(),
- (uint64_t)(time2 - time1));
- osal_printk("voltage: %.4f.\r\n", voltage);
-
-
-#if defined(CONFIG_ADC_SUPPORT_AUTO_SCAN)
- // uapi_suite_add_function("adc_start_auto_scan", "Params: <Channel>, <scan mode:0|1 >, <freq>, <bool: continue>,"
- // "<pin number>, <pin mode>", adc_start_auto_scan);
- // uapi_suite_add_function("adc_stop_auto_scan", "Params: <Channel>", adc_stop_auto_scan);
-#endif /* CONFIG_ADC_SUPPORT_AUTO_SCAN */
-#endif /* CONFIG_ADC_SUPPORT_AFE */
- return true;
-}
--- /dev/null
+/**
+ * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n
+ *
+ * Description: Test adc source \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2022-08-16, Create file. \n
+ */
+#include "battery_service.h"
+#include "battery_hal.h"
+
+uint8_t battery_get_battery_temp(float *temp)
+{
+ return batteryservice_get_battery_temp(temp);
+}
+uint8_t battery_get_pcb_temp(float *temp)
+{
+
+ return batteryservice_get_pcb_temp(temp);
+}
+uint8_t battery_get_voltage(float *voltage)
+{
+ return batteryservice_get_voltage(voltage);
+}
+
* 2022-08-16, Create file. \n
*/
-#ifndef BATTERY_H__
-#define BATTERY_H__
+#ifndef BATTERY_HAL_H__
+#define BATTERY_HAL_H__
#ifdef __cplusplus
#if __cplusplus
#endif /* __cplusplus */
#endif /* __cplusplus */
-/**
- * @defgroup testcase_adc ADC
- * @ingroup testcase
- * @{
- */
-
-/**
- * @if Eng
- * @brief Add the testcase of adc.
- * @else
- * @brief 添加ADC测试用例
- * @endif
- */
-bool battery_get_voltage_by_channel(float *voltage, uint8_t channel);
-
+uint8_t battery_get_battery_temp(float *temp);
+uint8_t battery_get_pcb_temp(float *temp);
/**
* return 电池百分比 0~100
* 参数指针返回 真实电压 voltage
SUITE_ALLOC_FAILED = -7,
SUITE_CONFIG_FAILED = -8,
SUITE_TEST_FAILED = -254,
-} battery_error_e;
+} batteryservice_error_e;
#if defined(CONFIG_ADC_SUPPORT_AFE)
#include "hal_adc_v151.h"
#include "hal_adc_v151_regs_op.h"
#endif
-#include "adc_porting.h"
+#include "adc_porting.h"
#include "pinctrl.h"
-
#include "debug_print.h"
#include "soc_osal.h"
#include "tcxo.h"
#include "gpio.h"
#include "pm_veto.h"
-#include "battery.h"
+#include "rtc.h"
+#include "timer.h"
+#include "systick.h"
+
+#include "battery_hal.h"
#define HAL_ADC_SAMPLE_NUMBER_CONFIG_0 10 /* Channel with buffer manual sample average number. */
#define HAL_ADC_SAMPLE_NUMBER_CONFIG_1 10 /* Channel without buffer manual sample average number. */
#define adc_trans_sytick_to_voltage(x) ((float)(((float)(x) * 17) / 40960))
#define adc_trans_sytick_to_voltage_diff(x) ((float)(((float)((x) - 2048) * 17) / 20480))
-// #define adc_trans_sytick_to_voltage_without_auto_scan(x) ((float)(((float)(x) * 18) / 40960))
-#define adc_trans_sytick_to_voltage_without_auto_scan(x) ((float)((float)(x) / 749.75838433852f))
-#define BATTERY_VOLTAGE_MAX (4.2f)
-#define BATTERY_VOLTAGE_MIN (3.2f)
+#define adc_trans_systick_to_battery_ntc(x) ((float)(((float)(x) * 18) / 40960))
+#define adc_trans_systick_to_pcb_ntc(x) ((float)(((float)(x) * 17) / 40960))
+#define adc_trans_systick_to_battery_voltage(x) ((float)((float)(x) / 749.75838433852f))
+#define batteryservice_VOLTAGE_MAX (4.2f)
+#define batteryservice_VOLTAGE_MIN (3.2f)
+
+#define ADC_CHANNEL_BAT_VOLTAGE ADC_CHANNEL_2
+#define ADC_CHANNEL_BAT_TEMP ADC_CHANNEL_0
+#define ADC_CHANNEL_PCB_TEMP ADC_CHANNEL_5
static uint32_t g_adc_sample_times = 0;
static uint32_t g_adc_sample_discard = 0;
#define MINIMUM_VOLTAGE_RANGE 2
#define MAXIMUM_VOLTAGE_RANGE 17
+
+typedef struct {
+ float battery_voltage;
+ float battery_ntc_temp;
+ float pcb_ntc_temp;
+ bool usb_plugged;
+} battery_info_t;
+
+
+static battery_info_t current_battery_info={0};
static uint32_t adc_get_sample_times(void)
{
return g_adc_sample_times;
}
adc_set_sample_stick(stick);
- *voltage = adc_trans_sytick_to_voltage_without_auto_scan(stick);
+
+
+ if(channel == 2)
+ *voltage = adc_trans_systick_to_battery_voltage(stick);
+ else if (channel == 0)
+ *voltage = adc_trans_systick_to_battery_ntc(stick);
+ else if (channel == 5)
+ *voltage = adc_trans_systick_to_pcb_ntc(stick);
+ osal_printk("channel = %d , tick = %d , voltage = %.04f.\r\n", channel,stick,*voltage);
UNUSED(discard_number);
return true;
return false;
}
-bool battery_get_voltage_by_channel(float *voltage, uint8_t channel)
+bool batteryservice_get_voltage_by_channel(float *voltage, uint8_t channel)
{
uapi_adc_init(ADC_CLOCK_500KHZ);
// osal_printk("tick: %d, Sample time: %d. \r\n", adc_get_sample_stick(),
// (uint64_t)(time2 - time1));
// osal_printk("voltage: %.4f.\r\n", voltage);
+ // osal_printk("channel %d, voltage: %.4f.\r\n", channel,*voltage);
uapi_adc_deinit();
return true;
}
#define GPIO_PIN_CHARGE_STAT S_AGPIO_L29
void disable_charge(void)
{
- PRINT("disable_charge\r\n");
+ // PRINT("disable_charge\r\n");
uapi_pin_set_mode(GPIO_PIN_ENABLE_CHARGE, (pin_mode_t)HAL_PIO_FUNC_GPIO);
uapi_gpio_set_dir(GPIO_PIN_ENABLE_CHARGE, GPIO_DIRECTION_OUTPUT);
uapi_tcxo_delay_ms(20);
uapi_gpio_set_val(GPIO_PIN_ENABLE_CHARGE, GPIO_LEVEL_HIGH);
uint8_t level = uapi_gpio_get_output_val(GPIO_PIN_ENABLE_CHARGE);
- PRINT("GPIO_PIN_ENABLE_CHARGE uapi_gpio_get_output_val %d\r\n",level);
+ // PRINT("GPIO_PIN_ENABLE_CHARGE uapi_gpio_get_output_val %d\r\n",level);
}
void enable_charge(void)
{
- PRINT("enable_charge\r\n");
+ // PRINT("enable_charge\r\n");
uapi_pin_set_mode(GPIO_PIN_ENABLE_CHARGE, (pin_mode_t)HAL_PIO_FUNC_GPIO);
uapi_gpio_set_dir(GPIO_PIN_ENABLE_CHARGE, GPIO_DIRECTION_OUTPUT);
uapi_tcxo_delay_ms(20);
uapi_gpio_set_val(GPIO_PIN_ENABLE_CHARGE, GPIO_LEVEL_LOW);
uint8_t level = uapi_gpio_get_output_val(GPIO_PIN_ENABLE_CHARGE);
- PRINT("GPIO_PIN_ENABLE_CHARGE uapi_gpio_get_output_val %d\r\n",level);
+ // PRINT("GPIO_PIN_ENABLE_CHARGE uapi_gpio_get_output_val %d\r\n",level);
}
void enable_02c(void)
{
- PRINT("enable_charge_02c\r\n");
+ // PRINT("enable_charge_02c\r\n");
uapi_pin_set_mode(GPIO_PIN_ENABLE_CHARGE_0_2C, (pin_mode_t)HAL_PIO_FUNC_GPIO);
uapi_gpio_set_dir(GPIO_PIN_ENABLE_CHARGE_0_2C, GPIO_DIRECTION_OUTPUT);
uapi_tcxo_delay_ms(20);
uapi_gpio_set_val(GPIO_PIN_ENABLE_CHARGE_0_2C, GPIO_LEVEL_LOW); //拉低低电流充电
uint8_t level = uapi_gpio_get_output_val(GPIO_PIN_ENABLE_CHARGE_0_2C);
- PRINT("GPIO_PIN_ENABLE_CHARGE_0_2C uapi_gpio_get_output_val %d\r\n",level);
+ // PRINT("GPIO_PIN_ENABLE_CHARGE_0_2C uapi_gpio_get_output_val %d\r\n",level);
}
void disable_02c(void)
{
- PRINT("disable_charge_02c\r\n");
+ // PRINT("disable_charge_02c\r\n");
uapi_pin_set_mode(GPIO_PIN_ENABLE_CHARGE_0_2C, (pin_mode_t)HAL_PIO_FUNC_GPIO);
uapi_gpio_set_dir(GPIO_PIN_ENABLE_CHARGE_0_2C, GPIO_DIRECTION_OUTPUT);
uapi_tcxo_delay_ms(20);
uapi_gpio_set_val(GPIO_PIN_ENABLE_CHARGE_0_2C, GPIO_LEVEL_HIGH); //拉高正常电流充电
uint8_t level = uapi_gpio_get_output_val(GPIO_PIN_ENABLE_CHARGE_0_2C);
- PRINT("GPIO_PIN_ENABLE_CHARGE_0_2C uapi_gpio_get_output_val %d\r\n",level);
+ // PRINT("GPIO_PIN_ENABLE_CHARGE_0_2C uapi_gpio_get_output_val %d\r\n",level);
}
-/**
- * return 0 not charged, 1 charging
-*/
-// uint8_t get_charge_stat(void)
-// {
-// PRINT("get_charge_stat\r\n");
-// uapi_pin_set_mode(GPIO_PIN_CHARGE_STAT, (pin_mode_t)HAL_PIO_FUNC_GPIO);
-// uapi_gpio_set_dir(GPIO_PIN_CHARGE_STAT, GPIO_DIRECTION_INPUT);
-// uapi_pin_set_ie(GPIO_PIN_CHARGE_STAT,HAL_PIO_IE_ENBALE);
-// uapi_tcxo_delay_ms(20);
-// uapi_gpio_clear_interrupt(GPIO_PIN_CHARGE_STAT);
-// uint8_t level = uapi_gpio_get_output_val(GPIO_PIN_CHARGE_STAT);
-// PRINT("GPIO_PIN_CHARGE_STAT uapi_gpio_get_output_val %d\r\n",level);
-// level = uapi_gpio_get_val(GPIO_PIN_CHARGE_STAT);
-// PRINT("GPIO_PIN_CHARGE_STAT uapi_gpio_get_val %d\r\n",level);
-// if (GPIO_LEVEL_HIGH == level)
-// return 0;
-// else
-// return 1;
-// }
#define ULP_WKUP_INT_STS 0x5702C1E0
-
/**
* return 0 not charged, 1 charging
*/
return 0;
}
+static bool g_batter_service_initialled = false;
+errcode_t uapi_battery_init(void);
#include "tcxo.h"
-uint8_t battery_get_voltage(float *voltage)
+uint8_t batteryservice_get_voltage(float *voltage)
{
- disable_charge();
- uapi_tcxo_delay_ms(100);
- battery_get_voltage_by_channel(voltage,2);
+ if (g_batter_service_initialled == false)
+ {
+ uapi_battery_init();
+ g_batter_service_initialled = true;
+ *voltage = 0;
+ return 0;
+ }
uint8_t percent = 0;
- enable_charge();
- if (*voltage <= BATTERY_VOLTAGE_MIN)
+ *voltage = current_battery_info.battery_voltage;
+ if (*voltage <= batteryservice_VOLTAGE_MIN)
return 0;
- if (*voltage >= BATTERY_VOLTAGE_MAX)
+ if (*voltage >= batteryservice_VOLTAGE_MAX)
return 100;
- percent = (*voltage - BATTERY_VOLTAGE_MIN)*100/(BATTERY_VOLTAGE_MAX - BATTERY_VOLTAGE_MIN) ;
+ percent = (*voltage - batteryservice_VOLTAGE_MIN)*100/(batteryservice_VOLTAGE_MAX - batteryservice_VOLTAGE_MIN) ;
return percent;
}
+uint8_t batteryservice_get_battery_temp(float *temp)
+{
+
+ if (g_batter_service_initialled == false)
+ {
+ uapi_battery_init();
+ g_batter_service_initialled = true;
+ *temp = 0;
+ return 0;
+ }
+
+ *temp = current_battery_info.battery_ntc_temp;
+
+ return 0;
+}
+uint8_t batteryservice_get_pcb_temp(float *temp)
+{
+ if (g_batter_service_initialled == false)
+ {
+ uapi_battery_init();
+ g_batter_service_initialled = true;
+ *temp = 0;
+ return 0;
+ }
+ *temp = current_battery_info.pcb_ntc_temp;
+ return 0;
+}
+/**************************Battery Check Timer***********************/
+/**
+ * 电池电压读取逻辑:
+ * 充电10秒,停止充电1秒,并读取电压。之后再开始充电10秒,再停止充电一秒,读取电压,然后再开始充电。。。。依此类推。
+ * **/
+timer_handle_t g_battery_timer = {0};
+static bool g_bat_timer_is_running = false;
+#define DISABLE_CHARGE_CHECK_MS 1000
+#define ENABLE_CHARGE_TIMEOUT_MS 10000
+bool last_battery_charge_enable_status=false; // true上次刚设置在充电状态,false 上次设置不在充电状态。注意这个是充电IC的充电开关设置,并非真正处于充电状态的标识。
+
+static void battery_check_timer_callback(uint32_t data);
+
+static void battery_timer_start_check_released(uint32_t rtc_ms)
+{
+ bool start = false;
+ if (!g_bat_timer_is_running) {
+ g_bat_timer_is_running = true;
+ start = true;
+ }
+
+ if (start) {
+ uapi_rtc_stop(g_battery_timer);
+ uapi_rtc_start(g_battery_timer, rtc_ms, battery_check_timer_callback, 0);
+ }
+}
+
+
+static void battery_check_timer_callback(uint32_t data)
+{
+ unused(data);
+
+ g_bat_timer_is_running = false;
+ if(last_battery_charge_enable_status == true){
+ disable_charge();
+ battery_timer_start_check_released(DISABLE_CHARGE_CHECK_MS);
+ last_battery_charge_enable_status = false;
+ }else{
+ batteryservice_get_voltage_by_channel(¤t_battery_info.battery_voltage,ADC_CHANNEL_BAT_VOLTAGE);
+ batteryservice_get_voltage_by_channel(¤t_battery_info.battery_ntc_temp,ADC_CHANNEL_BAT_TEMP);
+ batteryservice_get_voltage_by_channel(¤t_battery_info.pcb_ntc_temp,ADC_CHANNEL_PCB_TEMP);
+ enable_charge();
+ battery_timer_start_check_released(ENABLE_CHARGE_TIMEOUT_MS);
+ last_battery_charge_enable_status = true;
+ }
+
+}
+void uapi_battery_deinit(void)
+{
+ /* Stop the time and clear the pin map */
+ uapi_rtc_stop(g_battery_timer);
+ uapi_rtc_delete(g_battery_timer);
+ g_battery_timer = NULL;
+}
+
+errcode_t uapi_battery_init(void)
+{
+ errcode_t ret = 0;
+ ret = uapi_rtc_init();
+
+ ret |= uapi_rtc_adapter(0, RTC_0_IRQN, irq_prio(RTC_0_IRQN)); /* 1: using timer1 */
+ if (ret != ERRCODE_SUCC) {
+ PRINT("uapi_rtc_init FAILED 0x%x", ret);
+ return ret;
+ }
+ ret = uapi_rtc_create(0, &g_battery_timer); /* 1: using timer1 */
+ if (ret != ERRCODE_SUCC) {
+ PRINT("uapi_rtc_create FAILED 0x%x", ret);
+ return ret;
+ }
+ //开始timer
+ battery_check_timer_callback(0);
+ return ERRCODE_SUCC;
+}
--- /dev/null
+/**
+ * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n
+ *
+ * Description: Test adc header \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2022-08-16, Create file. \n
+ */
+
+#ifndef BATTERY_H__
+#define BATTERY_H__
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+#include "stdint.h"
+uint8_t batteryservice_get_battery_temp(float *temp);
+uint8_t batteryservice_get_pcb_temp(float *temp);
+uint8_t batteryservice_get_voltage(float *voltage);
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
#include "at_cmd_api.h"
#include "pm_control.h"
#include "debug_print.h"
-#include "battery.h"
+#include "battery_hal.h"
#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
#define BATTERY_MAX_ARGC 8
#define BATTERY_MAX_ARGV_LEN 64
#include "hx3695_at_cmd.h"
#endif
+#ifdef SUPPORT_AT_VIBRATOR
+#include "vibrator_at_cmd.h"
+#endif
+
+#ifdef SUPPORT_AT_HX3507
+#include "hx3507_at_cmd.h"
+#endif
+
#ifdef SUPPORT_AT_BATTERY
#include "battery_at_cmd.h"
#endif
#include "mmc5603_at_cmd.h"
#endif
+#ifdef SUPPORT_AT_CUSTOMUTILS
+#include "custom_utils_at_cmd.h"
+#endif
+
#include "log_file.h"
#ifdef CONFIG_OTA_UPDATE_SUPPORT
#include "upg.h"
at_cmd_table_t *hx3695_table = get_hx3695_cmd_table(&hx3695_cmd_count);
at_cmd_add_moudle(hx3695_table, hx3695_cmd_count);
#endif
+
+#ifdef SUPPORT_AT_VIBRATOR
+ uint32_t vibrator_cmd_count;
+ at_cmd_table_t *vibrator_table = get_vibrator_cmd_table(&vibrator_cmd_count);
+ at_cmd_add_moudle(vibrator_table, vibrator_cmd_count);
+#endif
+
+#ifdef SUPPORT_AT_HX3507
+ uint32_t hx3507_cmd_count;
+ at_cmd_table_t *hx3507_table = get_hx3507_cmd_table(&hx3507_cmd_count);
+ at_cmd_add_moudle(hx3507_table, hx3507_cmd_count);
+#endif
+
#ifdef SUPPORT_AT_BATTERY
uint32_t battery_cmd_count;
at_cmd_table_t *battery_table = get_battery_cmd_table(&battery_cmd_count);
at_cmd_add_moudle(battery_table, battery_cmd_count);
#endif
+#ifdef SUPPORT_AT_CUSTOMUTILS
+ uint32_t custom_utils_cmd_count;
+ at_cmd_table_t *custom_utils_table = get_custom_utils_cmd_table(&custom_utils_cmd_count);
+ at_cmd_add_moudle(custom_utils_table, custom_utils_cmd_count);
+#endif
+
#ifdef SUPPORT_AT_LIS2DOC
uint32_t lis2doc_cmd_count;
at_cmd_table_t *lis2doc_table = get_lis2doc_cmd_table(&lis2doc_cmd_count);
#include "components/ui_box_progress.h"\r
#include "components/ui_image_view.h"\r
#include "components/ui_label.h"\r
-#include "battery.h"\r
+#include "battery_hal.h"\r
\r
#include "hal_tick.h"\r
#ifdef __cplusplus\r
#include <ctime>
#include <fstream>
#include <string>
-#include "battery.h"
+#include "battery_hal.h"
#include "cJSON.h"
#include "sys/time.h"
extern uint8_t battery_get_voltage(float *voltage);
{
#endif
#endif
-
+#define WEARABLE_LOG_DEBUG
#ifdef USE_DIAG_LOG
#include "soc_diag_util.h"
#include "log_oam_logger.h"
+++ /dev/null
-#!/bin/bash
-
-if [ "$1" == "" ]
-then
-TARGET_PACK_NAME=pack_brandy_native_js
-else
-TARGET_PACK_NAME=$1
-fi
-./build.py -nhso -c -debug $TARGET_PACK_NAME
'PPG_HX3695',
'ACC_LIS2DOC',
'MAG_MMC5603',
+ 'ENABLE_SLIP',
#'CONFIG_ADC_SUPPORT_AUTO_SCAN','CONFIG_ADC_SUPPORT_LONG_SAMPLE',
'MIPI_ULPS_SUPPORT', 'TPTYPE_FT6X46'],
'ram_component': ["algorithm", "dfx_port_brandy", "dfx_update", 'dfx_nv', "osal", "arch_port", "-:testsuite",
'ulp_aon', 'hal_l2ram',
'x_dpal', 'x_vfs', 'x_disk', 'x_fat', 'drv_mmc', 'fs_yaffs2', 'x_vfs_private',
'pm_service', 'pm_brandy', 'cmn_header',
- 'at_cmd', 'graphic_at_service', 'app_at_service', 'ohosfwk_at_service',
- 'audio_at_service', 'media_at_service', 'bt_manager_at_service',
+ 'at_cmd',
+ # 'graphic_at_service',
+ 'app_at_service',
+ 'ohosfwk_at_service',
+ 'audio_at_service',
+ 'media_at_service',
+ # 'bt_manager_at_service',
"audio_proc", "audio_dump", "audio_probe", "power_manager", "gpu_proc",
"ppg_sensor",
"acc_sensor",
"mag_sensor",
+ "vibrator",
+ "lwIP",
+ "audio_manager",
+ "custom_utils",
+ "rotary_encoder",
"batterry_service"],
'ram_component_set': ['bgh', 'media', 'gpu', 'graphic_uikit', 'bgh_audio', 'dfx_set', 'ohos_set', 'wearable_set', 'alipay_set'],
'dsp_version': 'max',
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L11 a+g int1
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L12 i2c data HX3507_SDIO
- { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L13 i2c CLK HX3507_SCLK
+ { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_DISABLE }, // S_AGPIO_L13 i2c CLK HX3507_SCLK
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L14 NC
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L15 NC
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L16 NC
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L17 HX3507_INT
- { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L18 VDDEN //暂时无用,采用VDDIO 默认开启 EXt V3.0 EXt V1.8
+ { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_DISABLE }, // S_AGPIO_L18 VDDEN //暂时无用,采用VDDIO 默认开启 EXt V3.0 EXt V1.8
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L19 a+g int1
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_DISABLE }, // S_AGPIO_L20 0.2C_CHRG
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_DISABLE }, // S_AGPIO_R0 PRG_LED_POWER ON 心率等电源控制脚
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_DISABLE }, // S_AGPIO_R1 SE_REST 安全芯片复位唤醒脚
- { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_DISABLE }, // S_AGPIO_R2 VIBR_PWM 马达控制脚 兼容预留马达驱动复位脚
+ #if VIB_USE_PWM
+ // { HAL_PIO_FUNC_PWMP1_M2, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_NONE, HAL_PIO_IE_DISABLE }, // S_AGPIO_R2 VIBR_PWM 马达控制脚 兼容预留马达驱动复位脚
+ // { HAL_PIO_FUNC_PWMN1_M3, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_NONE, HAL_PIO_IE_DISABLE }, // S_AGPIO_R2 VIBR_PWM 马达控制脚 兼容预留马达驱动复位脚
+ #else
+ { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_DOWN, HAL_PIO_IE_DISABLE }, // S_AGPIO_R2 VIBR_PWM 马达控制脚 兼容预留马达驱动复位脚
+ #endif
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_R3 NC
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_UP, HAL_PIO_IE_DISABLE }, // S_AGPIO_R4 tp reset
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_R5 touch int
// S_AGPIO_L28 Cat1 reset ---- low reset
{ S_AGPIO_L28, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_LOW, 0, NULL },
#endif
- // // S_AGPIO_L17 HX3507_INT
- // { S_AGPIO_L17, HAL_GPIO_DIRECTION_INPUT, NULL, 0, NULL },
- // // S_AGPIO_L12 SDIO_BT
- // { S_AGPIO_L12, HAL_GPIO_DIRECTION_INPUT, NULL, 0, NULL },
- // // S_AGPIO_L13 SCLK_BT
- // { S_AGPIO_L13, HAL_GPIO_DIRECTION_INPUT, NULL, 0, NULL },
+ // S_AGPIO_L17 HX3507_INT
+ { S_AGPIO_L17, HAL_GPIO_DIRECTION_INPUT, HAL_GPIO_LEVEL_LOW, 0, NULL },
+ // S_AGPIO_L12 SDIO_BT
+ { S_AGPIO_L12, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_LOW, 0, NULL },
+ // S_AGPIO_L13 SCLK_BT
+ { S_AGPIO_L13, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_LOW, 0, NULL },
// S_AGPIO_L26 心率复位 PPG reset
{ S_AGPIO_L26, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_LOW, 0, NULL },
// #define GPIO_PIN_ENABLE_CHARGE_0_2C S_AGPIO_L20 //低电流充电
{ S_AGPIO_R9, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_LOW, 0, NULL },
{ S_AGPIO_L20, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_HIGH, 0, NULL },
+//默认关闭马达
+ { S_AGPIO_R2, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_LOW, 0, NULL },
+//默认开启 EXT LDO V3.0 V1.8
+ { S_AGPIO_L18, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_HIGH, 0, NULL },
};
/**
// 音频外挂输入设备
#define EXTERNAL_AI_PORT 1 // 参考 soc_uapi_ai.h 中 UAPI_AI_PORT_I2S1 枚举
-#define EXTERNAL_AI_I2S_ATTR_MASTER 1 // 1:主设备,0:从设备
-#define EXTERNAL_AI_I2S_ATTR_I2S_MODE 0 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_STD_MODE 枚举
-#define EXTERNAL_AI_I2S_ATTR_MCLK 4 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_MCLK_768_FS 枚举
-#define EXTERNAL_AI_I2S_ATTR_BCLK 24 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_BCLK_24_DIV 枚举
+#define EXTERNAL_AI_I2S_ATTR_MASTER 0 // 1:主设备,0:从设备
+#define EXTERNAL_AI_I2S_ATTR_I2S_MODE 1 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_PCM_MODE 枚举
+#define EXTERNAL_AI_I2S_ATTR_MCLK 6 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_MCLK_1536_FS 枚举
+#define EXTERNAL_AI_I2S_ATTR_BCLK 48 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_BCLK_48_DIV 枚举
#define EXTERNAL_AI_I2S_ATTR_BIT_DEPTH 16 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_BIT_DEPTH_16 枚举
#define EXTERNAL_AI_I2S_ATTR_AUDIO_CH 2 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_CHANNEL_2 枚举
#define EXTERNAL_AI_I2S_ATTR_SAMPLE_RISE_EDGE 1 // 参考 soc_uapi_audio.h 中 pcm_sample_rise_edge 成员
#define EXTERNAL_AI_I2S_ATTR_PCM_DELAY_CYCLE 1 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_PCM_1_DELAY 枚举
-#define EXTERNAL_AI_PCM_ATTR_CHANNELS 2 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_CHANNEL_2 枚举
+#define EXTERNAL_AI_PCM_ATTR_CHANNELS 1 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_CHANNEL_2 枚举
#define EXTERNAL_AI_PCM_ATTR_BIT_DEPTH 16 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_BIT_DEPTH_16 枚举
-#define EXTERNAL_AI_PCM_ATTR_SAMPLE_RATE 16000 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_SAMPLE_RATE_16K 枚举
-#define EXTERNAL_AI_PCM_ATTR_FRAME_PER_SEC 100 // 每秒帧数
+#define EXTERNAL_AI_PCM_ATTR_SAMPLE_RATE 8000 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_SAMPLE_RATE_16K 枚举
+#define EXTERNAL_AI_PCM_ATTR_FRAME_PER_SEC 50 // 每秒帧数 , EG810 pcm 20ms 一帧
// 音频外挂输出设备
#define EXTERNAL_SND_OUT_PORT 0x11 // 参考 soc_uapi_sound.h 中 UAPI_SND_OUT_PORT_I2S1 枚举
-#define EXTERNAL_SND_OUT_AUDIO_CHANNEL 2 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_CHANNEL_2 枚举
+#define EXTERNAL_SND_OUT_AUDIO_CHANNEL 1 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_CHANNEL_2 枚举
#define EXTERNAL_SND_OUT_AUDIO_BIT_DEPTH 16 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_BIT_DEPTH_16 枚举
-#define EXTERNAL_SND_OUT_AUDIO_SAMPLE_RATE 16000 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_SAMPLE_RATE_16K 枚举
+#define EXTERNAL_SND_OUT_AUDIO_SAMPLE_RATE 8000 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_SAMPLE_RATE_16K 枚举
#define EXTERNAL_SND_OUT_PORT_NUM 1 // 端口个数
#define EXTERNAL_SND_OUT_I2S_ATTR_BIT_DEPTH 16 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_BIT_DEPTH_16 枚举
#define EXTERNAL_SND_OUT_I2S_ATTR_CHANNEL 2 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_CHANNEL_2 枚举
-#define EXTERNAL_SND_OUT_I2S_ATTR_I2S_MODE 0 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_STD_MODE 枚举
-#define EXTERNAL_SND_OUT_I2S_ATTR_MCLK 4 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_MCLK_768_FS 枚举
-#define EXTERNAL_SND_OUT_I2S_ATTR_MASTER 1 // 1:主设备,0:从设备
+#define EXTERNAL_SND_OUT_I2S_ATTR_I2S_MODE 1 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_PCM_MODE 枚举
+#define EXTERNAL_SND_OUT_I2S_ATTR_MCLK 6 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_MCLK_1536_FS 枚举 12.288M /16k =
+#define EXTERNAL_SND_OUT_I2S_ATTR_MASTER 0 // 1:主设备,0:从设备
#define EXTERNAL_SND_OUT_I2S_ATTR_SAMPLE_RISE_EDGE 1 // 参考 soc_uapi_audio.h 中 pcm_sample_rise_edge 成员
-#define EXTERNAL_SND_OUT_I2S_ATTR_BCLK 24 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_BCLK_24_DIV 枚举
+#define EXTERNAL_SND_OUT_I2S_ATTR_BCLK 48 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_BCLK_48_DIV 枚举 12.288M / 256k = 48
// Sleep option
#define CONFIG_PM_TICKLESS_EN YES
{
unused(pin);
if (reg32_getbit(ULP_WKUP_INT_STS, 0x3) == 1) {
+ PRINT("power button\r\n");
return true;
}
return false;
}
-
+#define VBUS_INSERT_INTERRUPT_POS 0x4
+#define VBUS_UNPLUG_INNTERRUPT_POS 0x5
+// VBUS_INSERT_INTERRUPT_POS 0x4
+// ULP_WKUP_INT_STS 0x5702C1E0
+// VBUS_UNPLUG_INNTERRUPT_POS 0x5
static bool porting_vbus_check_int(pin_t pin)
{
unused(pin);
- if (reg32_getbit(ULP_WKUP_INT_STS, 0x4) == 1) {
+ if (reg32_getbit(ULP_WKUP_INT_STS, VBUS_INSERT_INTERRUPT_POS) == 1)
+ {
+ PRINT("vbus insert\r\n");
+ return true;
+ }
+ //表示插入
+ if (reg32_getbit(ULP_WKUP_INT_STS, VBUS_UNPLUG_INNTERRUPT_POS) == 1)
+ {//表示拔出}
+ PRINT("vbus remove\r\n");
return true;
}
-
return false;
}
static void at_cmd_uart_rx_callback(const void *buf, uint16_t buf_len, bool remaining)
{
unused(remaining);
+ #ifndef FT_SINGLE_UART
at_cmd_msg_receive_handler((uint8_t *)buf, buf_len);
+ #endif
hal_uart_clear_pending(SW_DEBUG_UART_BUS);
}
#endif
add_subdirectory_if_exist(mag)
add_subdirectory_if_exist(ppg)
add_subdirectory_if_exist(touch)
+add_subdirectory_if_exist(vibrator)
+add_subdirectory_if_exist(slip)
+add_subdirectory_if_exist(utils)
+add_subdirectory_if_exist(rotary_encoder)
--- /dev/null
+#===============================================================================
+# @brief cmake file
+# Copyright (c) @CompanyNameMagicTag 2022-2023. All rights reserved.
+#===============================================================================
+set(COMPONENT_NAME "rotary_encoder")
+
+if("ROTARYENCODER_HX3507" IN_LIST DEFINES)
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/hx3507.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/hx3507_at_cmd.c
+)
+set(PUBLIC_DEFINES
+SUPPORT_AT_HX3507
+)
+else()
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/hx3507.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/hx3507_at_cmd.c
+)
+set(PUBLIC_DEFINES
+SUPPORT_AT_HX3507
+)
+endif()
+
+set(PUBLIC_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+set(PRIVATE_HEADER
+)
+
+set(PRIVATE_DEFINES
+)
+
+
+
+# use this when you want to add ccflags like -include xxx
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+)
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+build_component()
--- /dev/null
+/**
+ * Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. \n
+ *
+ * Description: Button driver source file \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2023-02-24, Create file. \n
+ */
+
+#include "pinctrl.h"
+#include "button_porting.h"
+#include "platform_core.h"
+#include "gpio.h"
+#include "gpio_porting.h"
+#include "debug_print.h"
+#include "rtc.h"
+#include "timer.h"
+#include "systick.h"
+#include "chip_core_irq.h"
+#include "tcxo.h"
+#include "errcode.h"
+#include "pm_veto.h"
+
+/**
+ * Copyright (c) 2014 - 2023, 南京天易合芯电子有限公司
+ *
+ * All rights reserved.
+ *
+*/
+/*****************************************************************************
+ * @file tyhx_crown_custom.c
+ * @author Jiandang.Dong
+ * @date 2022-08-09 created
+ * @Emial Jiandang.Dong@tianyihexin.com
+ * @brief HX3507 驱动程序
+******************************************************************************/
+/*
+整体应用流程, 请见应用文档.
+先初始化IO, 执行crown_init 保证通信正确;
+在需要HX3507工作的时候, 调用crown_start(), 定时器启动,
+定时器周期处理调用crown_data_handler()来读取HX3507的数据;
+在HX3507 不需要工作的时候, 调用crown_stop() 让HX3507 进入power down状态
+*/
+
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "hx3507.h"
+
+// #ifdef CHIP_HX3507
+
+
+#include "cmsis_os2.h"
+
+osTimerId_t g_hx3507_timer = NULL;//定义一个定时器ID
+static uint8_t g_hx3695_timer_installed = 0;
+
+static int16_t crown_result = 0;
+
+/*----------------------以下为定时函数相关定义 建立/启动/停止定时器//定时中断处理-------------------------------*/
+
+
+
+/**
+ * 定时器超时处理函数
+ * @param p_context 是对应的定时器;
+ */
+void crown_timer_handler(void * p_context)
+{
+ UNUSED(p_context);
+ crown_data_handler(NULL,0);
+}
+/**
+ * 表冠定时器创建函数
+ * @param NULL
+ */
+void crown_timer_creat(void)
+{
+ if (g_hx3695_timer_installed == 1)
+ return ;
+ g_hx3507_timer = osTimerNew((osTimerFunc_t)crown_timer_handler, osTimerPeriodic, NULL, NULL);
+ g_hx3695_timer_installed = true;
+ return ;
+ // app_timer_create(&crown_timer_id, APP_TIMER_MODE_REPEATED, crown_timer_handler);
+}
+
+/**
+ * 定时器start函数 , 目前定义的定时器是50ms, 用户可以根据需要改为100ms
+ * @param NULL
+ */
+void crown_timer_start(void)
+{
+ if(osTimerIsRunning(g_hx3507_timer)==0)
+ osTimerStart(g_hx3507_timer, 50);
+}
+
+/**
+ * 定时器stop函数
+ * @param timerid 是对应的定时器;
+ */
+void crown_timer_stop(void)
+{
+ if(osTimerIsRunning(g_hx3507_timer))
+ osTimerStop(g_hx3507_timer);
+}
+
+
+
+/*----------------------以上为定时函数相关定义 建立/启动/停止定时器//定时中断处理-------------------------------*/
+
+
+/*---------------------------以下为表冠的寄存器读写,初始化/开始/结束------------------------*/
+
+/**
+ * 通信重新同步函数, 作用是防止因为其他干扰而引起的错乱
+ * @param NULL;
+ */
+void crown_com_resync(void)
+{
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_HIGH);
+ uapi_tcxo_delay_us(5);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+ uapi_tcxo_delay_us(5);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_HIGH);
+ uapi_tcxo_delay_ms(5);
+}
+
+/**
+ * 通信读寄存器值函数
+ * @param regaddr, hx3507的寄存器地址
+ * uapi_tcxo_delay_us(COM_DELAY), 读写函数的delay 按照实际平台调整, HX3507 通信sclk 最高支持1MHZ频率.
+ * 在最高频率的范围内, 尽量减小delay, 减少定时器周期读取的时间.
+ */
+uint8_t crown_read_reg(uint8_t regaddr)
+{
+ uint8_t readvalue = 0;
+
+ regaddr &= 0x7f;
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+ uapi_tcxo_delay_us(COM_DELAY);
+
+ for(int i=0; i<8; i++)
+ {
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+
+ if(regaddr & 0x80)
+ {
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_HIGH);
+ }
+ else
+ {
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW);
+
+ }
+ //uapi_tcxo_delay_us(COM_DELAY);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_HIGH);
+
+ regaddr<<=1;
+ //uapi_tcxo_delay_us(COM_DELAY);
+ }
+
+ //开始读操作,HOST要把SDIO从输出端口改为输入端口.
+ uapi_gpio_set_dir(PIN_TYHX_SDIO,GPIO_DIRECTION_INPUT);
+ uapi_pin_set_pull(PIN_TYHX_SDIO, (pin_pull_t)HAL_PIO_PULL_UP);
+ uapi_pin_set_ie(PIN_TYHX_SDIO,HAL_PIO_IE_ENBALE);
+ uapi_tcxo_delay_us(COM_DELAY);
+ //nrf_gpio_pin_clear(PIN_TYHX_SCLK);
+ //uapi_tcxo_delay_us(COM_DELAY);
+
+ for(int i=0; i<8; i++)
+ {
+ readvalue<<=1;
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+
+ //uapi_tcxo_delay_us(COM_DELAY);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_HIGH);
+ //uapi_tcxo_delay_us(COM_DELAY);
+ if(uapi_gpio_get_val(PIN_TYHX_SDIO))
+ {
+ readvalue |= 0x1;
+ }
+ //uapi_tcxo_delay_us(COM_DELAY);
+ }
+ uapi_gpio_set_dir(PIN_TYHX_SDIO,GPIO_DIRECTION_OUTPUT);
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+
+ return readvalue;
+}
+
+/**
+ * 通信读寄存器值函数
+ * @param regaddr, hx3507的寄存器地址
+ * @param regvalue, 要写的值
+ */
+void crown_write_reg(uint8_t regaddr, uint8_t regvalue)
+{
+
+ uint16_t writevalue;
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+ uapi_tcxo_delay_us(COM_DELAY);
+
+ //写通信协议, 最高位置1, 循环16次依次送出寄存器和值,在SCLK的上升沿前准备好数据
+ writevalue= (uint16_t)((regaddr|0x80)<<8) + regvalue;
+
+ for(int i=0; i<16; i++)
+ {
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+
+ if(writevalue & 0x8000)
+ {
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_HIGH);
+ }
+ else
+ {
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW);
+
+ }
+ //uapi_tcxo_delay_us(COM_DELAY);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_HIGH);
+
+ writevalue<<=1;
+ }
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+
+ return;
+}
+
+
+/**
+ * 某些OTS冠轴质量非常差, 这个是防呆处理
+ * @param xdata, 当前读到的OTS的有效轴的数据
+ * @result = true, 值有效, = false 这个值无效
+ */
+static bool crown_data_verify(int16_t xdata)
+{
+ static int16_t xstore[3] = {0};
+ uint16_t diff1, diff2, diff3= 0;
+
+ if(abs(xdata)>=600)//间隔50ms的一次读数
+ {
+ crown_timer_stop();
+ crown_start();
+ return false;
+ }
+ diff1 = abs(xstore[2]-xstore[1]);
+ diff2 = abs(xstore[1]-xstore[0]);
+ diff3 = abs(xstore[0]-xdata);
+
+ if((diff1<5) &&(diff2<=5) &&(diff3<=5) &&(abs(xdata)>=100))//连续四次读到接近的值
+ {
+ crown_timer_stop();
+ crown_start();
+ return false;
+ }
+ xstore[2] = xstore[1];
+ xstore[1] = xstore[0];
+ xstore[0] = xdata;
+ return true;
+}
+
+/**
+ * 周期定时器数据读取
+ * @param p_event_data, 参数暂时无用
+ * @param event_size, 参数暂时无用
+ */
+void crown_data_handler(void *p_event_data, uint16_t event_size)
+{
+ int16_t delatx = 0;
+ uint8_t sleepstatus = 0;
+ for(int i=0; i<5; i++)//先读一下芯片ID保证通信正常
+ {
+ if(crown_read_reg(HX3507_DID) == 0x30)
+ {
+ break;
+ }
+ else
+ {
+ crown_com_resync();
+ }
+ }
+ if(crown_read_reg(Motion_St)&0x80)
+ {
+#if defined(MOT_LOW_LEVEL_MODE)
+ //如果有使用中断, 需要读取Y的值, 值读完, 中断电平才能恢复
+ int16_t delaty = 0;
+ delaty = crown_read_reg(DeltaY) |(crown_read_reg(DeltaY_Hi)<<8);
+#endif
+ //HX3507 一个方向转动出正值, 另外一个方向就是负值, 正负值跟芯片的摆放方向有关
+ delatx = crown_read_reg(DeltaX) |(crown_read_reg(DeltaX_Hi)<<8);
+ if(crown_data_verify(delatx)) //先判断数据是否合理,
+ // 主要针对OTS冠轴质量,或者装配摆动幅度大引起的错误, 做的保护程序
+ {
+ //打印读取结果
+ TYHX_LOG("DeltaX = %d\r\n",delatx);
+ //把结果转换为大概的估算角度
+ put_crown_result(delatx);
+ }
+ }
+ else //下面这两个参数在产测程序里面需要加上
+ {
+ //冠轴静止的时候, 打印图像的质量和PD的饱和度, 这两个参数读取要放在出货测试的程序里面,
+ // 图像质量应该>=80, 否则可能代表芯片表面有脏污等或者装配问题或者有漏光
+ // PD的饱和度应该>=100 且 <=180, 如果有漏光等问题, 结果>=240以上, 相关漏光等要处理
+ TYHX_LOG("pic qulity =%d, pd saturation=%d\r\n",crown_read_reg(Img_Qa),crown_read_reg(PD_SAT));
+ }
+
+#if (defined(MOT_LOW_LEVEL_MODE))//如果低电平中断模式,要读到芯片MOT变高
+ if(uapi_gpio_get_val(PIN_TYHX_MOT))
+ {
+ TYHX_LOG("PIN_TYHX_MOT is high \r\n");
+ crown_timer_stop();
+ }
+#endif
+
+#if (defined(MOT_FALLINGTRI_MODE))//如果是脉冲中断模式,要读到芯片进入sleep
+ sleepstatus = crown_read_reg(Op_St);
+ if((sleepstatus & 0x7) == 6)
+ {
+ TYHX_LOG("crown is sleep \r\n");
+ crown_timer_stop();
+ }
+#endif
+#if (defined(MOT_NO_USE_MODE))
+ //如果是MOT_NO_USE_MODE , 一般在屏幕熄掉,不需要HX3507工作的时候, 关闭定时器
+#endif
+
+}
+
+//MOT 中断处理程序, 这个是根据平台程序处理, 用户可以自行修改
+//这里加中断发生标志位或者把中断处理推送到其他任务队列, 因为中断函数里面不能加太多程序
+//下面的例子用的是NORDIC标准的程序,中断发生后GPIO的一个处理,并且把中断处理推送到任务队列
+#if (defined(MOT_LOW_LEVEL_MODE) || defined(MOT_FALLINGTRI_MODE))
+static void crown_int_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
+{
+ uint32_t err_code;
+ bool mothitolow = false;
+
+ nrf_drv_gpiote_in_uninit(PIN_TYHX_MOT);
+ if (action == NRF_GPIOTE_POLARITY_HITOLO)
+ {
+ mothitolow = true;
+ nrf_drv_gpiote_in_config_t config_crown = GPIOTE_CONFIG_IN_SENSE_LOTOHI(false);
+ err_code = nrf_drv_gpiote_in_init(PIN_TYHX_MOT, &config_crown, crown_int_handler);
+ APP_ERROR_CHECK(err_code);
+ config_crown.pull = NRF_GPIO_PIN_PULLUP;
+ nrf_drv_gpiote_in_event_enable(PIN_TYHX_MOT, true);
+ }
+ else
+ {
+ mothitolow = false;
+ nrf_drv_gpiote_in_config_t config_crown = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);
+ err_code = nrf_drv_gpiote_in_init(PIN_TYHX_MOT, &config_crown, crown_int_handler);
+ APP_ERROR_CHECK(err_code);
+ config_crown.pull = NRF_GPIO_PIN_PULLUP;
+ nrf_drv_gpiote_in_event_enable(PIN_TYHX_MOT, true);
+ }
+ nrf_gpio_pin_latch_clear(PIN_TYHX_MOT);
+ if(mothitolow)
+ {
+ TYHX_LOG("mot interrupt! \r\n");
+ mothitolow = false;
+ crown_timer_start();
+ }
+
+}
+
+#endif
+
+
+/**
+ * HX3507 初始化
+ * @param NULL
+ */
+void crown_init(void)
+{
+ int i;
+ uapi_gpio_set_dir(PIN_TYHX_SDIO,GPIO_DIRECTION_INPUT);
+ uapi_gpio_set_dir(PIN_TYHX_SCLK,GPIO_DIRECTION_OUTPUT);
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+
+ uapi_tcxo_delay_us(COM_DELAY);
+ crown_com_resync();
+ for(i=0; i<10; i++)
+ {
+ if(crown_read_reg(HX3507_DID) == 0x30)
+ {
+ TYHX_LOG("read chip id is 0x30\r\n",i);
+ break;
+ }
+ if(i<7)//读到ID不对, 复位通信
+ {
+ crown_com_resync();
+ }
+ }
+ if(i==10)
+ {
+ TYHX_LOG("HX3507 communication err, please check\r\n");
+ return;
+ }
+
+#if (defined(MOT_LOW_LEVEL_MODE) || defined(MOT_FALLINGTRI_MODE))
+ //中断定义
+ nrf_drv_gpiote_in_config_t config_crown = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);
+ config_crown.pull = NRF_GPIO_PIN_PULLUP;
+ nrf_drv_gpiote_in_init(PIN_TYHX_MOT, &config_crown, crown_int_handler);
+ nrf_drv_gpiote_in_event_enable(PIN_TYHX_MOT, true);
+
+#endif
+ //定时器创建
+ crown_timer_creat();
+}
+
+
+/**
+ * HX3507 启动
+ * @param NULL
+ */
+void crown_start(void)
+{
+ int i = 0;
+ for(int i=0; i<5; i++)
+ {
+ crown_write_reg(Config_St,0x89); //RESET
+ uapi_tcxo_delay_ms(10);
+ TYHX_LOG("Reset ic, now init ---\r\n");
+
+#if defined(MOT_LOW_LEVEL_MODE)
+ crown_write_reg(Config_St,0x01); //正常工作, MOT低电平中断
+ crown_write_reg(Op_Mode,0xb8); //打开Sleep1 和 sleep2 功能
+ crown_write_reg(Sleep1_Setting,0xc0);
+ crown_write_reg(Enter_Time,0xc1);
+ crown_write_reg(Sleep2_Setting,0xc0);
+#elif defined(MOT_FALLINGTRI_MODE)
+ crown_write_reg(Config_St,0x41); //正常工作, MOT下降沿中断
+ crown_write_reg(Op_Mode,0xb8); //打开Sleep1 和 sleep2 功能
+ crown_write_reg(Sleep1_Setting,0xc0);
+ crown_write_reg(Enter_Time,0xc1);
+ crown_write_reg(Sleep2_Setting,0xc0);
+
+#elif defined(MOT_NO_USE_MODE)
+ crown_write_reg(Op_Mode,0xa0); //关闭sleep功能
+#endif
+ crown_write_reg(Write_Protect,0xc3); //enable all registers
+ crown_write_reg(Sleep1_Setting,0xc0); //0x70,32ms.loop = 40ms. return 0 slowly
+ crown_write_reg(Enter_Time,0x0); //sleep1=128*(Enter_Time[7:4]+1) sleep2=20480*(Enter_Time[3:0]+1)
+ crown_write_reg(DxDy_16bit,0x01); //0:8bit,1:16bit
+ crown_write_reg(CPI2_Setting,0x88); //800 cpi
+ crown_write_reg(HX3507_REV,0x00);
+ if(1 == crown_read_reg(DxDy_16bit) )
+ {
+ break;
+ }
+ else
+ {
+ crown_com_resync();
+ }
+ }
+ if(i==5)
+ {
+ TYHX_LOG("HX3507 init err, please check\r\n");
+ return;
+ }
+
+
+#if 0 //这里非常关键, 在调试初期, 需要用#if 1 来验证寄存器写入的值和读出来的值是一样的, 通信正确
+ TYHX_LOG("Op_Mode = 0x%x\r\n",crown_read_reg(Op_Mode));
+ TYHX_LOG("Sleep1_Setting = 0x%x\r\n",crown_read_reg(Sleep1_Setting));
+ TYHX_LOG("DxDy_16bit = 0x%x\r\n",crown_read_reg(DxDy_16bit));
+ TYHX_LOG("CPI2_Setting = 0x%x\r\n",crown_read_reg(CPI2_Setting));
+#endif
+
+#ifdef MOT_NO_USE_MODE // 如果是非中断模式, 初始后, 开启定时器;
+ crown_timer_start();
+#endif
+
+
+
+}
+
+
+/**
+ * HX3507 停止
+ * @param NULL
+ */
+void crown_stop(void)
+{
+#ifdef MOT_NO_USE_MODE
+ crown_timer_stop();
+ crown_write_reg(Config_St,0x89); // power down, power down 后芯片功耗9uA
+ uapi_tcxo_delay_ms(20);
+ TYHX_LOG("[tyhx_crown_stop]\r\n");
+#endif
+}
+
+
+/**
+ * HX3507 结果转换为角度, 供UI处理
+ * @param NULL
+ */
+void put_crown_result(int16_t x)
+{
+ if(abs(x)<=FILTER_MIN )
+ return;
+ if(abs(x)>=4 )
+ {
+ crown_result += x/4; //大于4的值除以4, 代表角度, 单位0.5°
+ }
+ else
+ {
+ if(x>0)
+ {
+ crown_result+=1; //2~4 默认一个单位, 0.5°
+ }
+ else
+ {
+ crown_result-=1; //2~4 默认一个单位, 0.5°
+ }
+ }
+}
+
+/**
+ * 获取表冠的数据结果接口函数
+ * @param NULL
+*/
+int16_t get_crown_result(void)
+{
+ int16_t resulttemp;
+ resulttemp=crown_result;
+ crown_result = 0;
+ return resulttemp;
+}
+
+// #endif
+
--- /dev/null
+/**
+ * Copyright (c) 2014 - 2023, 南京天易合芯电子有限公司
+ *
+ * All rights reserved.
+ *
+*/
+
+/***************************************************************************
+ * @file TYHX_CROWN_CUSTOM.h
+ * @author TYHX team
+ * @product CROWN
+ * @version V0.1
+ * @date 2022-08-09
+ * @modify date 2023-02-17
+
+****************************************************************************/
+#ifndef _TYHX_CROWN_CUSTOM_H_
+#define _TYHX_CROWN_CUSTOM_H_
+
+#include "debug_print.h"
+#define CHIP_HX3507
+
+
+//三种中断模式的应用具体见“天易合芯表冠产品应用文档.docx"的流程说明,用户也可以定义自己的流程模式
+//#define MOT_LOW_LEVEL_MODE //MOT使用低电平中断
+//#define MOT_FALLINGTRI_MODE //MOT 使用低脉冲中断
+#define MOT_NO_USE_MODE //用户不使用MOT 中断, 这个为常用的推荐模式
+
+
+//register define , addr, rw, default value, detail
+#define HX3507_DID 0x00 //R 0x30 芯片ID
+#define Motion_St 0x02 //R 是否有冠轴转动数据产生
+#define DeltaX 0x03 //R 0x30 DeltaX 的低8位数据
+#define DeltaY 0x04 //R 0x30 DeltaY 的低8位数据
+#define Op_Mode 0x05 //W/R 操作模式
+#define Config_St 0x06 //W/R 0x02 閰嶇疆
+#define Img_Qa 0x07 //R 图像质量
+#define Op_St 0x08 //R Sleep 和帧率设置
+#define Write_Protect 0x09 //W扩展寄存器的写使能
+#define Sleep1_Setting 0x0A //W/R Sleep1 的工作频率设置
+#define Enter_Time 0x0B //W/R 进入SLEEP的等待时间设置
+#define Sleep2_Setting 0x0C // W/R Sleep2的工作频率设置
+#define DeltaX_Hi 0x20 //R DeltaX 的高8位数据
+#define DeltaY_Hi 0x21 //R DeltaY的高8位数据
+#define DxDy_16bit 0x22 //数据输出寄存器选择16bit还是8bit格式
+#define CPI2_Setting 0x23 //W/R 扩展CPI 设置
+#define PD_SAT 0x3D //PD 感光的饱和度
+#define HX3507_REV 0x5F //W 保留寄存器
+
+#define COM_DELAY 5 // 通信的delay 单位, 用户根据平台实际调整, 最高支持1MHZ CLK
+#define FILTER_MIN 1 // 偶尔冠轴被震动等各种意外产生的小的数据, 可根据产品情况把小的出值滤掉
+
+//log 打印定义
+#define TYHX_LOG_ENABLE
+#ifdef TYHX_LOG_ENABLE
+#define TYHX_LOG(fmt, ...) \
+ do { \
+ PRINT(fmt" ", ##__VA_ARGS__); \
+ } while (0)
+#else
+#define TYHX_LOG(...)
+#endif //TYHX_LOG_ENABLE
+
+
+/*----------------------使用的IO定义-------------------------------*/
+
+#define PIN_TYHX_SDIO S_AGPIO_L12 //custom to do here
+#define PIN_TYHX_SCLK S_AGPIO_L13 //custom to do here
+#define PIN_TYHX_MOT S_AGPIO_L17 //custom to do here
+
+//定时器的 创建/启动/停止/溢出处理函数
+void crown_timer_creat(void);
+void crown_timer_start(void);
+void crown_timer_stop(void);
+void crown_timer_handler(void * p_context);
+
+//HX3507 初始化,启动,停止, 数据读取, 读寄存器, 写寄存器等, 通信同步
+void crown_init(void);
+void crown_start(void);
+void crown_stop(void);
+void crown_data_handler(void *p_event_data, uint16_t event_size);
+uint8_t crown_read_reg(uint8_t regaddr);
+void crown_write_reg(uint8_t regaddr, uint8_t regvalue);
+void crown_com_resync(void);
+
+//把读出的数据转换为大概角度函数
+void put_crown_result(int16_t x);
+
+//把角度结果上报的函数
+int16_t get_crown_result(void);
+#endif //_TYHX_CROWN_CUSTOM_H_
--- /dev/null
+
+// #include "hx3507.h"
+
+
+#include "at_cmd_api.h"
+#include "pm_control.h"
+#include "hx3507.h"
+
+#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
+#define HX3507_MAX_ARGC 8
+#define HX3507_MAX_ARGV_LEN 64
+
+#define HX3507_SUCCESS 0
+#define HX3507_FAILED (-1)
+
+static int ConvertCmdToParam(uint8_t *para, uint32_t paraLen,
+ uint8_t argv[HX3507_MAX_ARGC][HX3507_MAX_ARGV_LEN], uint32_t* argc)
+{
+ uint32_t pos = 0;
+ *argc = 0;
+
+ for (uint32_t i = 0; i < paraLen; i++) {
+ if ((para[i] == ' ' || para[i] == '\n') && pos != 0) {
+ argv[*argc][pos] = '\0';
+ *argc += 1;
+ pos = 0;
+ if (*argc >= HX3507_MAX_ARGC) {
+ return HX3507_FAILED;
+ }
+ } else {
+ argv[*argc][pos] = para[i];
+ pos++;
+ if (pos >= HX3507_MAX_ARGV_LEN) {
+ return HX3507_FAILED;
+ }
+ }
+ }
+ if (pos != 0) {
+ *argc += 1;
+ }
+
+ return HX3507_SUCCESS;
+}
+
+static uint8_t g_hx3507_test_started = 0;
+static uint32_t hx3507_test(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+ UNUSED(strCommonCmd);
+ uint8_t argv[HX3507_MAX_ARGC][HX3507_MAX_ARGV_LEN] = { 0 };
+ uint32_t argc = 0;
+
+ int ret = ConvertCmdToParam(para, paraLen, argv, &argc);
+ if (ret != HX3507_SUCCESS) {
+ PRINT("HX3507TEST ATCMD Convert Command Failed\n");
+ return ERRCODE_FAIL;
+ }
+
+ if (argc != 1) {
+ PRINT("HX3507TEST ATCMD Set Parameter Failed argc %d\n",argc);
+ return ERRCODE_FAIL;
+ }
+ uint8_t start = (uint8_t)atoi((char*)argv[0]);
+ if (start == 1)
+ {
+ if (g_hx3507_test_started == 1)
+ {
+ PRINT("SKIP hx3507test start, already started\r\n");
+ return 0;
+ }
+ crown_init();
+ crown_start();
+ g_hx3507_test_started = 1;
+ }else{
+ if (g_hx3507_test_started == 0)
+ {
+ PRINT("SKIP hx3507test stop, already stopped\r\n");
+ return 0;
+ }
+ crown_stop();
+ g_hx3507_test_started = 0 ;
+ }
+ return ERRCODE_SUCC;
+}
+static const at_cmd_table_t g_hx3507_cmd[] = {
+ { (char *)"AT^HX3507TEST", hx3507_test, (char *)"1" },
+};
+
+at_cmd_table_t *get_hx3507_cmd_table(uint32_t *cmd_count)
+{
+ *cmd_count = ARRAY_COUNT(g_hx3507_cmd);
+ return (at_cmd_table_t *)g_hx3507_cmd;
+}
--- /dev/null
+/**
+ * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n
+ *
+ * Description: Provides at cmd register func \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2022-07-20, Create file. \n
+ */
+#ifndef HX3507_AT_PROCESS_H
+#define HX3507_AT_PROCESS_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include "errcode.h"
+#include "soc_osal.h"
+#include "at_cmd_api.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+at_cmd_table_t *get_mmc5603_cmd_table(uint32_t *cmd_count);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
--- /dev/null
+#===============================================================================
+# @brief cmake file
+# Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved.
+#===============================================================================
+set(COMPONENT_NAME "SLIP")
+set(LWIP_PORT_SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/port/vfs_lwip.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/port/debug/lwip_debug.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/port/netif/ethernetif.c
+)
+set(SOURCES ${SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/asio.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/slipif.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/uart_slip.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/uart_slip.c
+ # ${LWIP_PORT_SOURCES}
+)
+set(PUBLIC_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ # ${CMAKE_CURRENT_SOURCE_DIR}/port
+)
+set(PUBLIC_DEFINES
+ SUPPORT_AT_SLIP
+)
+set(PRIVATE_HEADER
+)
+
+set(PRIVATE_DEFINES
+)
+
+# use this when you want to add ccflags like -include xxx
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+ -Wno-incompatible-function-pointer-types
+ -Wno-unused-function
+)
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+build_component()
+
--- /dev/null
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ */
+
+/*
+ * This is the interface to the platform specific serial IO module
+ * It needs to be implemented by those platforms which need SLIP or PPP
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+
+#include "driver/uart.h"
+#include "lwip/sio.h"
+
+#ifdef QUECTEL_CONFIG_HIGH_SPEED_SUPPORT
+#define SEND_BUFFER_MAX (6)
+#else
+#define SEND_BUFFER_MAX (1)
+#endif
+
+struct slip_send_buffer_t {
+ uint8_t buffer[SEND_BUFFER_MAX+1];
+ int len;
+};
+
+struct slip_send_buffer_t slip_send_buffer;
+
+/* The following functions can be defined to something else in your cc.h file
+ or be implemented in your custom sio.c file. */
+
+/**
+ * Opens a serial device for communication.
+ *
+ * @param devnum device number
+ * @return handle to serial device if successful, NULL otherwise
+ */
+sio_fd_t sio_open(u8_t devnum)
+{
+ memset(&slip_send_buffer, 0x00, sizeof(struct slip_send_buffer_t));
+ return 1;
+}
+
+/**
+ * Sends a single character to the serial device.
+ *
+ * @param c character to send
+ * @param fd serial device handle
+ *
+ * @note This function will block until the character can be sent.
+ */
+void sio_send(u8_t c, sio_fd_t fd)
+{
+ //uart_write_bytes(UART_NUM_0, (const char *)&c, 1);
+ slip_send_buffer.buffer[slip_send_buffer.len] = c;
+ slip_send_buffer.len += 1;
+ if( slip_send_buffer.len >= (SEND_BUFFER_MAX) ) {
+ //printf("send2 data len = %d\n", slip_send_buffer.len);
+ uart_write_bytes(UART_NUM_0, (const char *)slip_send_buffer.buffer, slip_send_buffer.len);
+ slip_send_buffer.len = 0;
+ }
+}
+
+void sio_send_all(u8_t c, sio_fd_t fd)
+{
+ //uart_write_bytes(UART_NUM_0, (const char *)&c, 1);
+ if( slip_send_buffer.len > 0 ) {
+ //printf("send data len = %d\n", slip_send_buffer.len);
+ uart_write_bytes(UART_NUM_0, (const char *)slip_send_buffer.buffer, slip_send_buffer.len);
+ slip_send_buffer.len = 0;
+ }
+}
+
+/**
+ * Receives a single character from the serial device.
+ *
+ * @param fd serial device handle
+ *
+ * @note This function will block until a character is received.
+ */
+u8_t sio_recv(sio_fd_t fd)
+{
+ return 0;
+}
--- /dev/null
+#define SLIP_UART_BUS UART_BUS_1
+#define CHIP_FIXED_TX_PIN S_MGPIO33
+#define CHIP_FIXED_RX_PIN S_MGPIO34
+
+void slipinit(void)
+{
+ uart_set_baudrate(UART_NUM_1,921600);
+
+ uint8_t ret = slip_uart_init((int)setting);
+ if( ret != 0 ) {
+ printf("custom_uart_init fail ret = %d\n", ret);
+ return;
+ }
+
+ user_netif_set_default();
+}
\ No newline at end of file
--- /dev/null
+/**
+ * @file
+ * SLIP Interface
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is built upon the file: src/arch/rtxc/netif/sioslip.c
+ *
+ * Author: Magnus Ivarsson <magnus.ivarsson(at)volvo.com>
+ * Simon Goldschmidt
+ */
+
+
+/**
+ * @defgroup slipif SLIP
+ * @ingroup netifs
+ *
+ * This is an arch independent SLIP netif. The specific serial hooks must be
+ * provided by another file. They are sio_open, sio_read/sio_tryread and sio_send
+ *
+ * Usage: This netif can be used in three ways:\n
+ * 1) For NO_SYS==0, an RX thread can be used which blocks on sio_read()
+ * until data is received.\n
+ * 2) In your main loop, call slipif_poll() to check for new RX bytes,
+ * completed packets are fed into netif->input().\n
+ * 3) Call slipif_received_byte[s]() from your serial RX ISR and
+ * slipif_process_rxqueue() from your main loop. ISR level decodes
+ * packets and puts completed packets on a queue which is fed into
+ * the stack from the main loop (needs SYS_LIGHTWEIGHT_PROT for
+ * pbuf_alloc to work on ISR level!).
+ *
+ */
+#include <string.h>
+#include "netif/slipif.h"
+#include "lwip/opt.h"
+
+#include "lwip/def.h"
+#include "lwip/pbuf.h"
+#include "lwip/stats.h"
+#include "lwip/snmp.h"
+#include "lwip/sys.h"
+#include "lwip/sio.h"
+
+#define SLIP_END 0xC0 /* 0300: start and end of every packet */
+#define SLIP_ESC 0xDB /* 0333: escape start (one byte escaped data follows) */
+#define SLIP_ESC_END 0xDC /* 0334: following escape: original byte is 0xC0 (END) */
+#define SLIP_ESC_ESC 0xDD /* 0335: following escape: original byte is 0xDB (ESC) */
+
+/** Maximum packet size that is received by this netif */
+#ifndef SLIP_MAX_SIZE
+#define SLIP_MAX_SIZE 1500
+#endif
+
+/** Define this to the interface speed for SNMP
+ * (sio_fd is the sio_fd_t returned by sio_open).
+ * The default value of zero means 'unknown'.
+ */
+#ifndef SLIP_SIO_SPEED
+#define SLIP_SIO_SPEED(sio_fd) 0
+#endif
+
+enum slipif_recv_state {
+ SLIP_RECV_NORMAL,
+ SLIP_RECV_ESCAPE
+};
+
+struct slipif_priv {
+ sio_fd_t sd;
+ /* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */
+ struct pbuf *p, *q;
+ u8_t state;
+ u16_t i, recved;
+#if SLIP_RX_FROM_ISR
+ struct pbuf *rxpackets;
+#endif
+};
+struct slipif_priv *priv = NULL;
+/**
+ * Send a pbuf doing the necessary SLIP encapsulation
+ *
+ * Uses the serial layer's sio_send()
+ *
+ * @param netif the lwip network interface structure for this slipif
+ * @param p the pbuf chain packet to send
+ * @return always returns ERR_OK since the serial layer does not provide return values
+ */
+static err_t
+slipif_output(struct netif *netif, struct pbuf *p)
+{
+ struct slipif_priv *priv;
+ struct pbuf *q;
+ u16_t i;
+ u8_t c;
+
+ LWIP_ASSERT("netif != NULL", (netif != NULL));
+ LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+ LWIP_ASSERT("p != NULL", (p != NULL));
+
+ LWIP_DEBUGF(SLIP_DEBUG, ("slipif_output: sending %"U16_F" bytes\n", p->tot_len));
+ //printf("slipif_output: sending %d bytes\n", p->tot_len);
+ priv = (struct slipif_priv *)netif->state;
+
+ /* Send pbuf out on the serial I/O device. */
+ /* Start with packet delimiter. */
+ sio_send(SLIP_END, priv->sd);
+
+ for (q = p; q != NULL; q = q->next) {
+ for (i = 0; i < q->len; i++) {
+ c = ((u8_t *)q->payload)[i];
+ switch (c) {
+ case SLIP_END:
+ /* need to escape this byte (0xC0 -> 0xDB, 0xDC) */
+ sio_send(SLIP_ESC, priv->sd);
+ sio_send(SLIP_ESC_END, priv->sd);
+ break;
+ case SLIP_ESC:
+ /* need to escape this byte (0xDB -> 0xDB, 0xDD) */
+ sio_send(SLIP_ESC, priv->sd);
+ sio_send(SLIP_ESC_ESC, priv->sd);
+ break;
+ default:
+ /* normal byte - no need for escaping */
+ sio_send(c, priv->sd);
+ break;
+ }
+ }
+ }
+ /* End with packet delimiter. */
+ sio_send(SLIP_END, priv->sd);
+ extern void sio_send_all(sio_fd_t fd);
+ sio_send_all(priv->sd);
+ return ERR_OK;
+}
+
+#if LWIP_IPV4
+/**
+ * Send a pbuf doing the necessary SLIP encapsulation
+ *
+ * Uses the serial layer's sio_send()
+ *
+ * @param netif the lwip network interface structure for this slipif
+ * @param p the pbuf chain packet to send
+ * @param ipaddr the ip address to send the packet to (not used for slipif)
+ * @return always returns ERR_OK since the serial layer does not provide return values
+ */
+static err_t
+slipif_output_v4(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr)
+{
+ LWIP_UNUSED_ARG(ipaddr);
+ return slipif_output(netif, p);
+}
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV6
+/**
+ * Send a pbuf doing the necessary SLIP encapsulation
+ *
+ * Uses the serial layer's sio_send()
+ *
+ * @param netif the lwip network interface structure for this slipif
+ * @param p the pbuf chain packet to send
+ * @param ipaddr the ip address to send the packet to (not used for slipif)
+ * @return always returns ERR_OK since the serial layer does not provide return values
+ */
+static err_t
+slipif_output_v6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr)
+{
+ LWIP_UNUSED_ARG(ipaddr);
+ return slipif_output(netif, p);
+}
+#endif /* LWIP_IPV6 */
+
+/**
+ * Handle the incoming SLIP stream character by character
+ *
+ * @param netif the lwip network interface structure for this slipif
+ * @param c received character (multiple calls to this function will
+ * return a complete packet, NULL is returned before - used for polling)
+ * @return The IP packet when SLIP_END is received
+ */
+static struct pbuf *
+slipif_rxbyte(struct netif *netif, u8_t c)
+{
+ struct slipif_priv *priv;
+ struct pbuf *t;
+
+ LWIP_ASSERT("netif != NULL", (netif != NULL));
+ LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+
+ priv = (struct slipif_priv *)netif->state;
+
+ switch (priv->state) {
+ case SLIP_RECV_NORMAL:
+ switch (c) {
+ case SLIP_END:
+ if (priv->recved > 0) {
+ /* Received whole packet. */
+ /* Trim the pbuf to the size of the received packet. */
+ pbuf_realloc(priv->q, priv->recved);
+
+ LINK_STATS_INC(link.recv);
+
+ LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet (%"U16_F" bytes)\n", priv->recved));
+ t = priv->q;
+ priv->p = priv->q = NULL;
+ priv->i = priv->recved = 0;
+ return t;
+ }
+ return NULL;
+ case SLIP_ESC:
+ priv->state = SLIP_RECV_ESCAPE;
+ return NULL;
+ default:
+ break;
+ } /* end switch (c) */
+ break;
+ case SLIP_RECV_ESCAPE:
+ /* un-escape END or ESC bytes, leave other bytes
+ (although that would be a protocol error) */
+ switch (c) {
+ case SLIP_ESC_END:
+ c = SLIP_END;
+ break;
+ case SLIP_ESC_ESC:
+ c = SLIP_ESC;
+ break;
+ default:
+ break;
+ }
+ priv->state = SLIP_RECV_NORMAL;
+ break;
+ default:
+ break;
+ } /* end switch (priv->state) */
+
+ /* byte received, packet not yet completely received */
+ if (priv->p == NULL) {
+ /* allocate a new pbuf */
+ LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));
+ priv->p = pbuf_alloc(PBUF_LINK, (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN - PBUF_LINK_ENCAPSULATION_HLEN), PBUF_POOL);
+
+ if (priv->p == NULL) {
+ LINK_STATS_INC(link.drop);
+ LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));
+ /* don't process any further since we got no pbuf to receive to */
+ return NULL;
+ }
+
+ if (priv->q != NULL) {
+ /* 'chain' the pbuf to the existing chain */
+ pbuf_cat(priv->q, priv->p);
+ } else {
+ /* p is the first pbuf in the chain */
+ priv->q = priv->p;
+ }
+ }
+
+ /* this automatically drops bytes if > SLIP_MAX_SIZE */
+ if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) {
+ ((u8_t *)priv->p->payload)[priv->i] = c;
+ priv->recved++;
+ priv->i++;
+ if (priv->i >= priv->p->len) {
+ /* on to the next pbuf */
+ priv->i = 0;
+ if (priv->p->next != NULL && priv->p->next->len > 0) {
+ /* p is a chain, on to the next in the chain */
+ priv->p = priv->p->next;
+ } else {
+ /* p is a single pbuf, set it to NULL so next time a new
+ * pbuf is allocated */
+ priv->p = NULL;
+ }
+ }
+ }
+ return NULL;
+}
+
+/** Like slipif_rxbyte, but passes completed packets to netif->input
+ *
+ * @param netif The lwip network interface structure for this slipif
+ * @param c received character
+ */
+static void
+slipif_rxbyte_input(struct netif *netif, u8_t c)
+{
+ struct pbuf *p;
+ p = slipif_rxbyte(netif, c);
+ if (p != NULL) {
+ if (netif->input(p, netif) != ERR_OK) {
+ pbuf_free(p);
+ }
+ }
+}
+
+#if SLIP_USE_RX_THREAD
+/**
+ * The SLIP input thread.
+ *
+ * Feed the IP layer with incoming packets
+ *
+ * @param nf the lwip network interface structure for this slipif
+ */
+static void
+slipif_loop_thread(void *nf)
+{
+ u8_t c;
+ struct netif *netif = (struct netif *)nf;
+ struct slipif_priv *priv = (struct slipif_priv *)netif->state;
+
+ while (1) {
+ if (sio_read(priv->sd, &c, 1) > 0) {
+ slipif_rxbyte_input(netif, c);
+ }
+ }
+}
+#endif /* SLIP_USE_RX_THREAD */
+
+/**
+ * @ingroup slipif
+ * SLIP netif initialization
+ *
+ * Call the arch specific sio_open and remember
+ * the opened device in the state field of the netif.
+ *
+ * @param netif the lwip network interface structure for this slipif
+ * @return ERR_OK if serial line could be opened,
+ * ERR_MEM if no memory could be allocated,
+ * ERR_IF is serial line couldn't be opened
+ *
+ * @note If netif->state is interpreted as an u8_t serial port number.
+ *
+ */
+err_t
+slipif_init(struct netif *netif)
+{
+ u8_t sio_num;
+
+ LWIP_ASSERT("slipif needs an input callback", netif->input != NULL);
+
+ /* netif->state contains serial port number */
+ sio_num = LWIP_PTR_NUMERIC_CAST(u8_t, netif->state);
+
+ LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)sio_num));
+
+ /* Allocate private data */
+ if( priv == NULL ) {
+ priv = (struct slipif_priv *)mem_malloc(sizeof(struct slipif_priv));
+ if (!priv) {
+ return ERR_MEM;
+ }
+ }
+ memset(priv, 0x00, sizeof(struct slipif_priv));
+
+ netif->name[0] = 's';
+ netif->name[1] = 'l';
+#if LWIP_IPV4
+ netif->output = slipif_output_v4;
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+ netif->output_ip6 = slipif_output_v6;
+#endif /* LWIP_IPV6 */
+ netif->mtu = SLIP_MAX_SIZE;
+
+ /* Try to open the serial port. */
+ priv->sd = sio_open(sio_num);
+ if (!priv->sd) {
+ /* Opening the serial port failed. */
+ mem_free(priv);
+ return ERR_IF;
+ }
+
+ /* Initialize private data */
+ priv->p = NULL;
+ priv->q = NULL;
+ priv->state = SLIP_RECV_NORMAL;
+ priv->i = 0;
+ priv->recved = 0;
+#if SLIP_RX_FROM_ISR
+ priv->rxpackets = NULL;
+#endif
+
+ netif->state = priv;
+
+ /* initialize the snmp variables and counters inside the struct netif */
+ MIB2_INIT_NETIF(netif, snmp_ifType_slip, SLIP_SIO_SPEED(priv->sd));
+
+#if SLIP_USE_RX_THREAD
+ /* Create a thread to poll the serial line. */
+ sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif,
+ SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO);
+#endif /* SLIP_USE_RX_THREAD */
+ return ERR_OK;
+}
+
+/**
+ * @ingroup slipif
+ * Polls the serial device and feeds the IP layer with incoming packets.
+ *
+ * @param netif The lwip network interface structure for this slipif
+ */
+void
+slipif_poll(struct netif *netif)
+{
+ u8_t c;
+ struct slipif_priv *priv;
+
+ LWIP_ASSERT("netif != NULL", (netif != NULL));
+ LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+
+ priv = (struct slipif_priv *)netif->state;
+
+ while (sio_tryread(priv->sd, &c, 1) > 0) {
+ slipif_rxbyte_input(netif, c);
+ }
+}
+
+#if SLIP_RX_FROM_ISR
+/**
+ * @ingroup slipif
+ * Feeds the IP layer with incoming packets that were receive
+ *
+ * @param netif The lwip network interface structure for this slipif
+ */
+void
+slipif_process_rxqueue(struct netif *netif)
+{
+ struct slipif_priv *priv;
+ SYS_ARCH_DECL_PROTECT(old_level);
+
+ LWIP_ASSERT("netif != NULL", (netif != NULL));
+ LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+
+ priv = (struct slipif_priv *)netif->state;
+
+ SYS_ARCH_PROTECT(old_level);
+ while (priv->rxpackets != NULL) {
+ struct pbuf *p = priv->rxpackets;
+#if SLIP_RX_QUEUE
+ /* dequeue packet */
+ struct pbuf *q = p;
+ while ((q->len != q->tot_len) && (q->next != NULL)) {
+ q = q->next;
+ }
+ priv->rxpackets = q->next;
+ q->next = NULL;
+#else /* SLIP_RX_QUEUE */
+ priv->rxpackets = NULL;
+#endif /* SLIP_RX_QUEUE */
+ SYS_ARCH_UNPROTECT(old_level);
+ if (netif->input(p, netif) != ERR_OK) {
+ pbuf_free(p);
+ }
+ SYS_ARCH_PROTECT(old_level);
+ }
+ SYS_ARCH_UNPROTECT(old_level);
+}
+
+/** Like slipif_rxbyte, but queues completed packets.
+ *
+ * @param netif The lwip network interface structure for this slipif
+ * @param data Received serial byte
+ */
+static void
+slipif_rxbyte_enqueue(struct netif *netif, u8_t data)
+{
+ struct pbuf *p;
+ struct slipif_priv *priv = (struct slipif_priv *)netif->state;
+ SYS_ARCH_DECL_PROTECT(old_level);
+
+ p = slipif_rxbyte(netif, data);
+ if (p != NULL) {
+ SYS_ARCH_PROTECT(old_level);
+ if (priv->rxpackets != NULL) {
+#if SLIP_RX_QUEUE
+ /* queue multiple pbufs */
+ struct pbuf *q = p;
+ while (q->next != NULL) {
+ q = q->next;
+ }
+ q->next = p;
+ } else {
+#else /* SLIP_RX_QUEUE */
+ pbuf_free(priv->rxpackets);
+ }
+ {
+#endif /* SLIP_RX_QUEUE */
+ priv->rxpackets = p;
+ }
+ SYS_ARCH_UNPROTECT(old_level);
+ }
+}
+
+/**
+ * @ingroup slipif
+ * Process a received byte, completed packets are put on a queue that is
+ * fed into IP through slipif_process_rxqueue().
+ *
+ * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled.
+ *
+ * @param netif The lwip network interface structure for this slipif
+ * @param data received character
+ */
+void
+slipif_received_byte(struct netif *netif, u8_t data)
+{
+ LWIP_ASSERT("netif != NULL", (netif != NULL));
+ LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+ slipif_rxbyte_enqueue(netif, data);
+}
+
+/**
+ * @ingroup slipif
+ * Process multiple received byte, completed packets are put on a queue that is
+ * fed into IP through slipif_process_rxqueue().
+ *
+ * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled.
+ *
+ * @param netif The lwip network interface structure for this slipif
+ * @param data received character
+ * @param len Number of received characters
+ */
+void
+slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len)
+{
+ u8_t i;
+ u8_t *rxdata = data;
+ LWIP_ASSERT("netif != NULL", (netif != NULL));
+ LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+
+
+ for (i = 0; i < len; i++, rxdata++) {
+ //slipif_rxbyte_enqueue(netif, *rxdata);
+ slipif_rxbyte_input(netif, *rxdata);
+ }
+}
+#endif /* SLIP_RX_FROM_ISR */
--- /dev/null
+// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT 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 <string.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/queue.h"
+#include "driver/uart.h"
+#include "esp_log.h"
+
+#include "lwip/ip.h"
+#include "lwip/netif.h"
+#include "netif/slipif.h"
+#include "lwip/init.h"
+#include "lwip/lwip_napt.h"
+
+#include "lwip/inet_chksum.h"
+
+struct netif sl_netif;
+
+/**
+ * This example shows how to use the UART driver to handle special UART events.
+ *
+ * It also reads data from UART0 directly, and echoes it to console.
+ *
+ * - Port: UART0
+ * - Receive (Rx) buffer: on
+ * - Transmit (Tx) buffer: on
+ * - Flow control: off
+ * - Event queue: on
+ * - Pin assignment: TxD (default), RxD (default)
+ */
+
+#define EX_UART_NUM UART_NUM_0
+
+#define BUF_SIZE (1024)
+#define RD_BUF_SIZE (BUF_SIZE)
+
+static QueueHandle_t uart0_queue;
+static void uart_event_task(void *pvParameters)
+{
+ uart_event_t event;
+ uint8_t *dtmp = (uint8_t *) malloc(RD_BUF_SIZE);
+ int len = 0;
+ size_t remain_len = 0;
+ for (;;) {
+ // Waiting for UART event.
+ if (xQueueReceive(uart0_queue, (void *)&event, (portTickType)portMAX_DELAY)) {
+ // ESP_LOGI(TAG, "uart[%d] event:", EX_UART_NUM);
+
+ switch (event.type) {
+ // Event of UART receving data
+ // We'd better handler data event fast, there would be much more data events than
+ // other types of events. If we take too much time on data event, the queue might be full.
+ case UART_DATA:
+ len = uart_read_bytes(EX_UART_NUM, dtmp, event.size, 0);
+ //xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
+ // ESP_LOGI(TAG, "[DATA EVT]:");
+ slipif_received_bytes(&sl_netif, dtmp, len);
+ // slipif_process_rxqueue(&sl_netif);
+ break;
+ // Event of HW FIFO overflow detected
+ case UART_FIFO_OVF:
+ //uart_get_buffered_data_len(EX_UART_NUM, &remain_len);
+ //printf("event.size = %d, remain_len=%d\n", event.size, remain_len);
+ //printf("hw fifo overflow\n");
+ // If fifo overflow happened, you should consider adding flow control for your application.
+ // The ISR has already reset the rx FIFO,
+ // As an example, we directly flush the rx buffer here in order to read more data.
+ uart_flush_input(EX_UART_NUM);
+ xQueueReset(uart0_queue);
+ break;
+
+ // Event of UART ring buffer full
+ case UART_BUFFER_FULL:
+ printf("ring buffer full\n");
+ // If buffer full happened, you should consider encreasing your buffer size
+ // As an example, we directly flush the rx buffer here in order to read more data.
+ uart_flush_input(EX_UART_NUM);
+ xQueueReset(uart0_queue);
+ break;
+
+ case UART_PARITY_ERR:
+ printf("uart parity errori\n");
+ break;
+
+ // Event of UART frame error
+ case UART_FRAME_ERR:
+ printf("uart frame errori\n");
+ break;
+ // Others
+ default:
+ printf("uart event type: %d\n", event.type);
+ break;
+ }
+ }
+ }
+
+ free(dtmp);
+ dtmp = NULL;
+ vTaskDelete(NULL);
+}
+
+void user_netif_deinit()
+{
+ ip_addr_t ipaddr;
+ IP4_ADDR(&ipaddr, 172, 16, 1, 5);
+ if(sl_netif.napt == 1 ) {
+ ip_napt_enable(ipaddr.addr, 0);
+ }
+ netif_set_link_down(&sl_netif);
+ netif_set_down(&sl_netif);
+ netif_remove(&sl_netif);
+}
+
+void user_netif_set_default()
+{
+ netif_set_default(&sl_netif);
+}
+
+int user_netif_init(int mode)
+{
+ ip_addr_t ipaddr;
+ ip_addr_t netmask;
+ ip_addr_t gw;
+ char int_no = 2;
+
+ struct netif *temp;
+
+ IP4_ADDR(&ipaddr, 172, 16, 1, 5);
+ IP4_ADDR(&netmask, 255, 255, 255, 0);
+ IP4_ADDR(&gw, 172, 16, 1, 1);
+ temp = netif_add(&sl_netif, &ipaddr, &netmask, &gw, &int_no, slipif_init, ip_input);
+ if( temp == NULL ) {
+ printf("fail to netif init\n");
+ return -1;
+ }
+ netif_set_up(&sl_netif);
+ sl_netif.mtu = 1500;
+ netif_set_link_up(&sl_netif);
+
+ if( mode == 1 ) {
+ ip_napt_enable(ipaddr.addr, 1);
+ } else if(mode == 2) {
+ netif_set_default(&sl_netif);
+ }
+
+ return 0;
+}
+
+int slip_uart_init(int mode)
+{
+#ifdef QUECTEL_CONFIG_UART0_SWAP_SUPPORT
+ uart_enable_swap();
+#endif
+ // Configure parameters of an UART driver, 921600
+ // communication pins and install the driver
+ uart_config_t uart_config = {
+ .baud_rate = 921600,
+ .data_bits = UART_DATA_8_BITS,
+ .parity = UART_PARITY_DISABLE,
+ .stop_bits = UART_STOP_BITS_1,
+ .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
+ };
+ uart_param_config(EX_UART_NUM, &uart_config);
+ esp_err_t err;
+ int ret = 0;
+
+ // Install UART driver, and get the queue.
+#ifdef QUECTEL_CONFIG_HIGH_SPEED_SUPPORT
+ err = uart_driver_install(EX_UART_NUM, BUF_SIZE * 16, BUF_SIZE * 12, 512, &uart0_queue, 0);
+#else
+ err = uart_driver_install(EX_UART_NUM, BUF_SIZE * 8, BUF_SIZE * 4, 512, &uart0_queue, 0);
+#endif
+ if( err != ERR_OK ) {
+ printf("uart_driver_install fail err = %d\n", err);
+ return -1;
+ }
+ //uart_set_rx_timeout(EX_UART_NUM, 1);
+ ret = user_netif_init(mode);
+ if( ret != 0 ) return -1;
+
+ // Create a task to handler UART event from ISR
+ xTaskCreate(uart_event_task, "uart_event_task", 2048, NULL, 10, NULL);
+
+ return 0;
+}
--- /dev/null
+// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT 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 __CUSTOM_UART_H
+#define __CUSTOM_UART_H
+
+/**
+ * @brief init uart config and config uart as slip netif bridge
+ */
+int slip_uart_init(int mode);
+
+/**
+ * @brief remove slip netif
+ */
+void user_netif_deinit(void);
+
+void user_netif_set_default();
+
+/**
+ * @brief add slip netif
+ */
+int user_netif_init(int mode);
+
+#endif
--- /dev/null
+/* BSD Socket API Example
+
+ This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+ Unless required by applicable law or agreed to in writing, this
+ software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ CONDITIONS OF ANY KIND, either express or implied.
+*/
+#include <string.h>
+#include <sys/param.h>
+#include <string.h>
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "esp_system.h"
+#include "esp_log.h"
+#include "esp_netif.h"
+#include "esp_event.h"
+#include "nvs.h"
+#include "nvs_flash.h"
+
+#include "lwip/err.h"
+#include "lwip/sockets.h"
+#include "lwip/sys.h"
+#include <lwip/netdb.h>
+#include "esp_wifi.h"
+
+#include "uart_slip.h"
+#include "wifi_ap.h"
+#include "wifi_station.h"
+#include "web_server.h"
+#include "udp_server.h"
+#include "app_version.h"
+
+#ifdef QUECTEL_CONFIG_SMARTCONFIG_SUPPORT
+#include "smartconfig.h"
+#endif
+
+extern int g_wifi_station_status;
+extern int g_wifi_ap_status;
+extern int g_wifi_ota_status;
+
+web_config_t tcp_web_config = {0};
+
+#define PEER_IP "172.16.1.2"
+#define PEER_PORT 5000
+
+#define PORT 1000
+#define SSID_LENGTH 32
+#define PASSWORD_LENGTH 64
+
+enum UDP_COMMAND_HEAD {
+ UDP_CHANGE_WEB_NETWORK = '0', // web config
+ UDP_WIFI_STATUS = '1', // status
+ UDP_CHANGE_AP = '2', // ap mode
+ UDP_CHANGE_STATION = '3', // station mode
+ UDP_OTA_UPDATE = '4', // ota upgrade
+ UDP_APP_VERSION = '5', // app version
+ UDP_SMART_CONFIG = '6', // smartconfig
+ UDP_CONFIG_QUERY = '7', // config query
+ UDP_EVENT_REPORT = 'F' // auto report
+};
+// current work station
+enum SSS_WORKING_STATUS {
+ SSS_WORKING_NONE = 0, // do nothing
+ SSS_WORKING_REINIT, // reinit uart slip
+ SSS_WORKING_RESTART, // restart device
+ SSS_WORKING_OTA // ota ing
+};
+
+static char *msg_wifi_resp[] =
+{
+ "OK", // op success
+ "ERROR", // op failure
+ "0", // no init
+ "1", // station mode, wifi connected
+ "2", // station mode, wifi connecting
+ "3", // web config mode
+ "4", // ap mode
+ "5", // ota ing
+ "6", // smart config mode
+};
+#define RESP_STATUS_OFSET 2
+
+#pragma pack(push)
+#pragma pack(1)
+struct tcp_msg_t {
+ char head[2];
+ int length;
+ char buffer[512];
+};
+#pragma pack(pop)
+
+// status 0: init, 1: station 2: softap
+typedef struct _quec_wifi_status_t {
+ int mode;
+ enum SSS_WORKING_STATUS s_status;
+} quec_wifi_status_t;
+quec_wifi_status_t quec_wifi_status ={0, 0};
+
+static int g_listen_sock = 0;
+struct sockaddr_in sourceAddr = {0};
+
+extern int quec_config_query_entry(char *key, char *buffer);
+
+void set_current_wifi_stat(enum WIFI_CURRENT_SETTINNG stat)
+{
+ quec_wifi_status.mode = stat;
+}
+
+static void tcp_device_restart()
+{
+
+}
+
+static void stop_current_wifi()
+{
+
+}
+
+static struct tcp_msg_t *unpack_tlv_format(char *rx_buffer, int length)
+{
+ char temp[8];
+ struct tcp_msg_t *msg = (struct tcp_msg_t *)rx_buffer;
+ strncpy(temp, (char *)&msg->length, 4);
+ temp[4] = '\0';
+ msg->length = atoi(temp);
+
+ if( length != msg->length+6 ) return NULL;
+ return msg;
+}
+
+static int pack_tlv_format(char *tx_buffer, char *head, char *content)
+{
+ int content_length = (int)strlen(content);
+ if( content == NULL || head == NULL || content_length > 9999 ) {
+ return -1;
+ }
+
+ struct tcp_msg_t *msg = (struct tcp_msg_t *)tx_buffer;
+ strncpy(msg->head, head, 2);
+ //sprintf((char *)(&msg->length), "%04d", (unsigned char)content_length);
+ sprintf(&tx_buffer[2], "%04d", content_length);
+
+ strcpy(msg->buffer, content);
+ return strlen(content)+6;
+}
+
+static void udp_send_response(char *tx_buffer, char *head, char *content)
+{
+ // remain lock using
+ int len = pack_tlv_format(tx_buffer, head, content);
+ int err = 0;
+ if( len > 0 ) {
+ err = sendto(g_listen_sock, tx_buffer, len, 0, (struct sockaddr *)&sourceAddr, sizeof(sourceAddr));
+ if (err < 0) {
+ printf("Error occured during sending: errno %d\n", errno);
+ }
+ } else {
+ printf("Error occured unkown send data\n");
+ }
+}
+
+void udp_ota_update(char *content)
+{
+ char ota_tx_buffer[128] = {0};
+ char ota_head[2] = {0};
+ ota_head[0] = 'F';
+ ota_head[1] = UDP_EVENT_REPORT;
+ udp_send_response(ota_tx_buffer, ota_head, content);
+}
+
+void udp_station_update(char *content)
+{
+ char station_tx_buffer[128] = {0};
+ char station_head[2] = {0};
+ if( sourceAddr.sin_port != 0 ) {
+ station_head[0] = 'F';
+ station_head[1] = UDP_EVENT_REPORT;
+ udp_send_response(station_tx_buffer, station_head, content);
+ }
+}
+
+static int resolve_msg_ap_connect(struct tcp_msg_t *msg)
+{
+ int ret = 0;
+ int index = 0;
+ char ssid[SSID_LENGTH];
+ char password[PASSWORD_LENGTH];
+ if( msg == NULL || msg->buffer == NULL ) return 1;
+ //ptr = strtok(data, ",");
+ char *ptr = strchr(msg->buffer, ',');
+ if( ptr == NULL ) {
+ return 1;
+ }
+ if( strlen(&ptr[1]) < 1 || strlen(&ptr[1]) >= PASSWORD_LENGTH ) {
+ return 1;
+ }
+ memset(password, 0, PASSWORD_LENGTH);
+ strncpy(password, &ptr[1], strlen(&ptr[1]));
+
+ ptr[0] = '\0';
+ if( strlen(msg->buffer) < 1 || strlen(msg->buffer) >= SSID_LENGTH ) {
+ return 1;
+ }
+ memset(ssid, 0, SSID_LENGTH);
+ strncpy(ssid, msg->buffer, strlen(msg->buffer));
+
+ printf("ssid: %s,password: %s\r\n", ssid, password);
+ return index;
+}
+
+static int resolve_msg_wifi_status(struct tcp_msg_t *msg)
+{
+ int index = 0;
+ //printf("quec_wifi_status.mode = %d\n", quec_wifi_status.mode);
+ if( g_wifi_ota_status == 1 ) {
+ return 5; // ota ing
+ }
+ int web_server_status = 0;
+#ifdef QUECTEL_CONFIG_SMARTCONFIG_SUPPORT
+ int smartconfig_status = 0;
+#endif
+ if( quec_wifi_status.mode == WIFI_CURRENT_SETTINNG_STATION) { // station
+
+#ifdef QUECTEL_CONFIG_SMARTCONFIG_SUPPORT
+ smartconfig_status = get_smartconfig_status();
+ if( smartconfig_status != -1 ) {
+ index = 6;
+ }
+ else
+#endif
+ if( g_wifi_station_status == 1 ) {
+ index = 1; // connected success
+ } else {
+ index = 2; // connected fail
+ }
+ } else if( quec_wifi_status.mode == WIFI_CURRENT_SETTINNG_SOFTAP ){
+ web_server_status = get_web_server_status();
+ if( web_server_status == 1 ) {
+ index = 3; // web server start
+ } else if( g_wifi_ap_status == 1 ) {
+ index = 4; // ap construct
+ }
+ }
+ return index;
+}
+
+static int resolve_msg_ap_construct(struct tcp_msg_t *msg)
+{
+ int ret = 0;
+ int index = 0;
+ char ssid[SSID_LENGTH];
+ char password[PASSWORD_LENGTH];
+ if( msg->buffer == NULL ) return 1;
+ //ptr = strtok(data, ",");
+ char *ptr = strchr(msg->buffer, ',');
+ if( ptr == NULL ) {
+ return 1;
+ }
+ if( strlen(&ptr[1]) < 1 || strlen(&ptr[1]) >= PASSWORD_LENGTH ) {
+ return 1;
+ }
+ memset(password, 0, PASSWORD_LENGTH);
+ strncpy(password, &ptr[1], strlen(&ptr[1]));
+
+ ptr[0] = '\0';
+ if( strlen(msg->buffer) < 1 || strlen(msg->buffer) >= SSID_LENGTH ) {
+ return 1;
+ }
+ memset(ssid, 0, SSID_LENGTH);
+ strncpy(ssid, msg->buffer, strlen(msg->buffer));
+ stop_current_wifi();
+
+ //printf("ssid: %s,password: %s\r\n", ssid, password);
+ ret = softap_wifi_init(ssid, password, 0);
+ if( ret == 0 ) {
+ index = 0;
+ } else {
+ index = 1;
+ }
+ web_server_status_reset();
+ quec_wifi_status.mode = WIFI_CURRENT_SETTINNG_SOFTAP;
+ quec_wifi_status.s_status = SSS_WORKING_REINIT;
+ return index;
+}
+
+static int resolve_msg_web_network(struct tcp_msg_t *msg)
+{
+ int index = 0;
+ char ssid[SSID_LENGTH];
+ char password[PASSWORD_LENGTH];
+ if( msg->buffer == NULL ) return 1;
+
+ if( (msg->length == 1) && (msg->buffer[0] == '0') ) {
+ strcpy(tcp_web_config.user, "");
+ strcpy(tcp_web_config.password, "");
+ quec_wifi_status.mode = WIFI_CURRENT_SETTINNG_SOFTAP;
+ quec_wifi_status.s_status = SSS_WORKING_RESTART;
+ return index;
+ }
+ //ptr = strtok(data, ",");
+ char *ptr = strchr(msg->buffer, ',');
+ if( ptr == NULL ) {
+ return 1;
+ }
+ if( strlen(&ptr[1]) < 1 || strlen(&ptr[1]) >= PASSWORD_LENGTH ) {
+ return 1;
+ }
+ memset(password, 0, PASSWORD_LENGTH);
+ strncpy(password, &ptr[1], strlen(&ptr[1]));
+
+ ptr[0] = '\0';
+ if( strlen(msg->buffer) < 1 || strlen(msg->buffer) >= SSID_LENGTH ) {
+ return 1;
+ }
+ memset(ssid, 0, SSID_LENGTH);
+ strncpy(ssid, msg->buffer, strlen(msg->buffer));
+ //printf("ssid: %s,password: %s\r\n", ssid, password);
+
+ memcpy(tcp_web_config.user, ssid, 32);
+ memcpy(tcp_web_config.password, password, 64);
+ quec_wifi_status.mode = WIFI_CURRENT_SETTINNG_SOFTAP;
+ quec_wifi_status.s_status = SSS_WORKING_RESTART;
+ return index;
+}
+
+static int resolve_msg_smartconfig_network(struct tcp_msg_t *msg)
+{
+ int index = 0;
+#ifdef QUECTEL_CONFIG_SMARTCONFIG_SUPPORT
+ if( msg->buffer == NULL || msg->length != 1 ) return 1;
+ printf("msg->buffer[0] = %c\n", msg->buffer[0]);
+ if( msg->buffer[0] == '0' ) {
+ stop_smartconfig();
+ quec_wifi_status.mode = WIFI_CURRENT_SETTINNG_STATION;
+ quec_wifi_status.s_status = SSS_WORKING_RESTART;
+ return index;
+ }
+ stop_current_wifi();
+ web_server_status_reset();
+
+ int ret = start_smartconfig(msg->buffer[0] - '1');
+ if( ret != 0 ) {
+ printf("start_smartconfig ret = %d\n", ret);
+ return 1;
+ }
+
+ quec_wifi_status.mode = WIFI_CURRENT_SETTINNG_STATION;
+ quec_wifi_status.s_status = SSS_WORKING_REINIT;
+#else
+ index = 1;
+#endif
+ return index;
+}
+
+static int resolve_config_query(struct tcp_msg_t *msg)
+{
+ int index = -1;
+ char config_tx_buffer[256] = {0};
+ char buffer[128];
+ if( msg->buffer == NULL && msg->buffer[0] != '0') return 1;
+
+ memset(buffer, 0x00, sizeof(buffer));
+ index = quec_config_query_entry(msg->buffer, buffer);
+ if( index == 0 ) {
+ udp_send_response(config_tx_buffer, msg->head, buffer);
+ } else {
+ index = 1;
+ }
+
+ return index;
+}
+
+static int resolve_msg_ota(struct tcp_msg_t *msg)
+{
+ int index = 0;
+ if( msg->buffer == NULL ) return 1;
+#ifdef QUECTEL_CONFIG_OTA_SUPPORT
+ extern int ota_app_main(char *ota_server);
+ //printf("ota url = %s\n", msg->buffer);
+ int ret = ota_app_main(msg->buffer);
+ if( ret != 0 ) {
+ index = 1;
+ }
+#else
+ index = 1;
+#endif
+ return index;
+}
+
+static int resolve_msg_app_version(struct tcp_msg_t *msg)
+{
+ int index = -1;
+ char version_tx_buffer[256] = {0};
+ if( msg->buffer == NULL && msg->buffer[0] != '0') return 1;
+ char version[128] = {0};
+ snprintf(version, 128, "sdk: %s\nmodel: %s\nversion: %s\ntime: %s",
+ build_sdk, build_model, build_version, build_time);
+
+ udp_send_response(version_tx_buffer, msg->head, version);
+ return index;
+}
+
+static int udp_packet_parse(char *rx_buffer, int len)
+{
+ struct tcp_msg_t *msg = unpack_tlv_format(rx_buffer, len);
+ int index = 0;
+ if( g_wifi_ota_status == 1 && msg->head[1] != UDP_WIFI_STATUS ) { // ota only status check
+ return 1;
+ }
+ if( msg != NULL ) {
+ switch (msg->head[1]) {
+ case UDP_WIFI_STATUS:
+ index = resolve_msg_wifi_status(msg);
+ index += RESP_STATUS_OFSET;
+ break;
+ case UDP_CHANGE_WEB_NETWORK:
+ index = resolve_msg_web_network(msg);
+ break;
+ case UDP_CHANGE_AP:
+ index = resolve_msg_ap_construct(msg);
+ break;
+ case UDP_CHANGE_STATION:
+ index = resolve_msg_ap_connect(msg);
+ break;
+ case UDP_OTA_UPDATE:
+ index = resolve_msg_ota(msg);
+ break;
+ case UDP_APP_VERSION:
+ index = resolve_msg_app_version(msg);
+ break;
+ case UDP_SMART_CONFIG:
+ index = resolve_msg_smartconfig_network(msg);
+ break;
+ case UDP_CONFIG_QUERY:
+ index = resolve_config_query(msg);
+ break;
+ default:
+ printf("error message: %s\n", rx_buffer);
+ index = 1;
+ break;
+ }
+ } else {
+ printf("wrong format msg and exit\n");
+ index = 1;
+ }
+ return index;
+}
+
+static int udp_socket_init()
+{
+ int addr_family;
+ int ip_protocol;
+ int opt = 1;
+ struct sockaddr_in destAddr;
+ char addr_str[128];
+
+ // destAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ destAddr.sin_addr.s_addr = inet_addr("172.16.1.5");
+ destAddr.sin_family = AF_INET;
+ destAddr.sin_port = htons(PORT);
+ addr_family = AF_INET;
+ ip_protocol = IPPROTO_IP;
+ inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1);
+
+ int listen_sock = socket(addr_family, SOCK_DGRAM, ip_protocol);
+ if (listen_sock < 0) {
+ printf("Unable to create socket: errno %d\n", errno);
+ return -1;
+ }
+ setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+
+ int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr));
+ if (err != 0) {
+ printf("Socket unable to bind: errno %d\n", errno);
+ return -1;
+ }
+
+ sourceAddr.sin_addr.s_addr = inet_addr(PEER_IP);
+ sourceAddr.sin_family = AF_INET;
+ sourceAddr.sin_port = htons(PEER_PORT);
+
+ return listen_sock;
+}
+
+void udp_server_task(void *pvParameters)
+{
+ char rx_buffer[512];
+ char tx_buffer[256];
+ int index;
+ uint addrLen = sizeof(sourceAddr);
+ while (1) {
+ if( g_listen_sock > 0 ) close(g_listen_sock);
+ g_listen_sock = udp_socket_init();
+ if( g_listen_sock < 0 ) {
+ printf("socket init fail and retry\n");
+ vTaskDelay(1000/portTICK_RATE_MS);
+ continue;
+ }
+
+ while (1) {
+ memset(rx_buffer, 0, sizeof(rx_buffer));
+ int len = recvfrom(g_listen_sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&sourceAddr, &addrLen);
+ // Error occured during receiving
+ if (len < 0) {
+ printf("recv failed: errno %d\n", errno);
+ break;
+ } else if (len == 0) {
+ printf("Connection closed\n");
+ break;
+ }
+ // Data received
+ rx_buffer[len] = '\0'; // Null-terminate whatever we received and treat like a string
+ printf("Received %d bytes, rx_buffer: %s\n", len, rx_buffer);
+ index = udp_packet_parse(rx_buffer, len);
+ if( index >= 0 ) {
+ udp_send_response(tx_buffer, rx_buffer, msg_wifi_resp[index]);
+ }
+
+ if( quec_wifi_status.s_status == SSS_WORKING_RESTART ) {
+ //station_wifi_set_info("","");
+
+ tcp_device_restart();
+ } else if( quec_wifi_status.s_status == SSS_WORKING_REINIT ) {
+ user_netif_deinit();
+ vTaskDelay(1000/portTICK_RATE_MS);
+ user_netif_init(quec_wifi_status.mode);
+ quec_wifi_status.s_status = SSS_WORKING_NONE;
+ break;
+ }
+ }
+ }
+
+ vTaskDelete(NULL);
+}
+#if 0
+void wifi_status()
+{
+ char tx_buffer[128] = {0};
+ int index = resolve_msg_wifi_status(NULL);
+ char *head = "FF";
+ int len = pack_tlv_format(tx_buffer, head, msg_wifi_status[index]);
+ printf("wifi_status len = %d, msg = [%s]\n",len, tx_buffer);
+}
+#endif
\ No newline at end of file
--- /dev/null
+/* BSD Socket API Example
+
+ This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+ Unless required by applicable law or agreed to in writing, this
+ software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ CONDITIONS OF ANY KIND, either express or implied.
+*/
+#ifndef __UDP_SERVER_H
+#define __UDP_SERVER_H
+
+// status 0: init, 1: station 2: softap
+enum WIFI_CURRENT_SETTINNG {
+ WIFI_CURRENT_SETTINNG_NONE = 0,
+ WIFI_CURRENT_SETTINNG_STATION,
+ WIFI_CURRENT_SETTINNG_SOFTAP
+};
+
+typedef struct _web_config_t {
+ int used;
+ char user[36];
+ char password[64];
+} web_config_t;
+
+void set_current_wifi_stat(enum WIFI_CURRENT_SETTINNG stat);
+
+void udp_server_task(void *pvParameters);
+
+void udp_ota_update(char *content);
+#endif
--- /dev/null
+#===============================================================================
+# @brief cmake file
+# Copyright (c) @CompanyNameMagicTag 2022-2023. All rights reserved.
+#===============================================================================
+set(COMPONENT_NAME "custom_utils")
+
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/custom_utils.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/custom_utils_at_cmd.c
+)
+
+set(PUBLIC_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+set(PRIVATE_HEADER
+)
+
+set(PRIVATE_DEFINES
+)
+
+set(PUBLIC_DEFINES
+SUPPORT_AT_CUSTOMUTILS
+)
+
+# use this when you want to add ccflags like -include xxx
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+)
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+build_component()
--- /dev/null
+/**
+ * Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. \n
+ *
+ * Description: Button driver source file \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2023-02-24, Create file. \n
+ */
+
+#include "pinctrl.h"
+#include "button_porting.h"
+#include "platform_core.h"
+#include "gpio.h"
+#include "gpio_porting.h"
+#include "debug_print.h"
+#include "rtc.h"
+#include "timer.h"
+#include "systick.h"
+#include "chip_core_irq.h"
+#include "pwm.h"
+#include "pwm_porting.h"
+#include "pinctrl.h"
+#include "errcode.h"
+
+
+#define SUPPORT_NV
+
+#ifdef SUPPORT_NV
+#include "nv.h"
+#include "key_id.h"
+#include "common.h"
+#endif
+
+
+
+uint32_t zh_get_sn(uint8_t *buf_sn, uint32_t *len_sn)
+{
+
+#ifdef SUPPORT_NV
+ if( buf_sn == NULL)
+ return ERRCODE_FAIL;
+ uint16_t len = 0;
+ custom_key_sn_t sn = {0};
+ errcode_t nvRet = uapi_nv_read(NV_ID_CUSTOM_KEY_SERIAL_NUM, sizeof(custom_key_sn_t), &len, &sn);
+ if (nvRet != ERRCODE_SUCC) {
+ *len_sn = 0;
+ }
+ memcpy_s(buf_sn,sizeof(sn.sn),sn.sn,sn.size);
+ *len_sn = sn.size;
+ PRINT("get sn len %d, ret %d , %s\r\n",sn.size,nvRet,sn.sn);
+#endif
+ return ERRCODE_SUCC;
+}
+
+
+uint32_t zh_set_sn(uint8_t *buf_sn, uint32_t len_sn)
+{
+
+#ifdef SUPPORT_NV
+ if( buf_sn == NULL || len_sn == 0)
+ return ERRCODE_FAIL;
+
+ uint16_t len = 0;
+ custom_key_sn_t sn = {0};
+ if (len_sn > sizeof(sn.sn))
+ {
+ len = sizeof(sn.sn);
+ }else{
+ len = len_sn;
+ }
+ sn.size = len;
+ memcpy_s(sn.sn,sizeof(sn.sn),buf_sn,len);
+ errcode_t nvRet = uapi_nv_write(NV_ID_CUSTOM_KEY_SERIAL_NUM, &sn, sizeof(custom_key_sn_t));
+ PRINT("write sn len %d, ret %d , %s\r\n",len,nvRet,sn.sn);
+#endif
+ return nvRet;
+}
+
--- /dev/null
+/**
+ * Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. \n
+ *
+ * Description: Button driver header file \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2023-02-24, Create file. \n
+ */
+#ifndef BUTTON_H
+#define BUTTON_H
+
+#include "hal_gpio.h"
+#include "soc_osal.h"
+#include "platform_core.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+uint32_t zh_get_sn(uint8_t *buf_sn, uint32_t *len_sn);
+uint32_t zh_set_sn(uint8_t *buf_sn, uint32_t len_sn);
+
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
--- /dev/null
+
+// #include "custom_utils.h"
+
+
+#include "at_cmd_api.h"
+#include "pm_control.h"
+#include "custom_utils.h"
+#include "debug_print.h"
+
+#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
+#define CUSTOM_UTILS_MAX_ARGC 8
+#define CUSTOM_UTILS_MAX_ARGV_LEN 64
+
+#define CUSTOM_UTILS_SUCCESS 0
+#define CUSTOM_UTILS_FAILED (-1)
+
+
+#include "common.h"
+
+static int ConvertCmdToParam(uint8_t *para, uint32_t paraLen,
+ uint8_t argv[CUSTOM_UTILS_MAX_ARGC][CUSTOM_UTILS_MAX_ARGV_LEN], uint32_t* argc)
+{
+ uint32_t pos = 0;
+ *argc = 0;
+
+ for (uint32_t i = 0; i < paraLen; i++) {
+ if ((para[i] == ' ' || para[i] == '\n') && pos != 0) {
+ argv[*argc][pos] = '\0';
+ *argc += 1;
+ pos = 0;
+ if (*argc >= CUSTOM_UTILS_MAX_ARGC) {
+ return CUSTOM_UTILS_FAILED;
+ }
+ } else {
+ argv[*argc][pos] = para[i];
+ pos++;
+ if (pos >= CUSTOM_UTILS_MAX_ARGV_LEN) {
+ return CUSTOM_UTILS_FAILED;
+ }
+ }
+ }
+ if (pos != 0) {
+ *argc += 1;
+ }
+
+ return CUSTOM_UTILS_SUCCESS;
+}
+
+
+static uint32_t custom_utils_setsn(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+ UNUSED(strCommonCmd);
+ uint8_t argv[CUSTOM_UTILS_MAX_ARGC][CUSTOM_UTILS_MAX_ARGV_LEN] = { 0 };
+ uint32_t argc = 0;
+
+ int ret = ConvertCmdToParam(para, paraLen, argv, &argc);
+ if (ret != CUSTOM_UTILS_SUCCESS) {
+ PRINT("CUSTOM_UTILSTEST ATCMD Convert Command Failed\n");
+ return ERRCODE_FAIL;
+ }
+
+ if (argc != 1) {
+ PRINT("CUSTOM_UTILSTEST ATCMD Set Parameter Failed argc %d\n",argc);
+ return ERRCODE_FAIL;
+ }
+ uint8_t *sn_buf = (uint8_t*)argv[0];
+ uint16_t len = strlen((const char*)sn_buf);
+ PRINT("set sn = %s \r\n",sn_buf);
+ uint32_t rret = zh_set_sn(sn_buf,len);
+ return rret;
+}
+static uint32_t custom_utils_getsn(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+ UNUSED(strCommonCmd);
+ uint8_t sn_buf[32] = {0};
+ uint32_t len = 0;
+ uint32_t ret = zh_get_sn(sn_buf,&len);
+ PRINT("get sn len %d , %s \r\n",len,sn_buf);
+ return ret;
+}
+static const at_cmd_table_t g_custom_utils_cmd[] = {
+ { (char *)"AT^CUSTOM_SN", custom_utils_setsn, (char *)"123456789ABCDEF2345678" },
+ { (char *)"AT^CUSTOM_SN?", custom_utils_getsn, (char *)" " },
+};
+
+at_cmd_table_t *get_custom_utils_cmd_table(uint32_t *cmd_count)
+{
+ *cmd_count = ARRAY_COUNT(g_custom_utils_cmd);
+ return (at_cmd_table_t *)g_custom_utils_cmd;
+}
--- /dev/null
+/**
+ * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n
+ *
+ * Description: Provides at cmd register func \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2022-07-20, Create file. \n
+ */
+#ifndef CUSTOM_UTILS_AT_PROCESS_H
+#define CUSTOM_UTILS_AT_PROCESS_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include "errcode.h"
+#include "soc_osal.h"
+#include "at_cmd_api.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+at_cmd_table_t *get_custom_utils_cmd_table(uint32_t *cmd_count);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
--- /dev/null
+#===============================================================================
+# @brief cmake file
+# Copyright (c) @CompanyNameMagicTag 2022-2023. All rights reserved.
+#===============================================================================
+set(COMPONENT_NAME "vibrator")
+
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/vibrator.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/vibrator_at_cmd.c
+)
+
+set(PUBLIC_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+set(PRIVATE_HEADER
+)
+
+set(PRIVATE_DEFINES
+)
+
+set(PUBLIC_DEFINES
+SUPPORT_AT_VIBRATOR
+)
+
+# use this when you want to add ccflags like -include xxx
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+)
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+build_component()
--- /dev/null
+/**
+ * Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. \n
+ *
+ * Description: Button driver source file \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2023-02-24, Create file. \n
+ */
+
+#include "pinctrl.h"
+#include "button_porting.h"
+#include "platform_core.h"
+#include "gpio.h"
+#include "gpio_porting.h"
+#include "debug_print.h"
+#include "rtc.h"
+#include "timer.h"
+#include "systick.h"
+#include "chip_core_irq.h"
+#include "pwm.h"
+#include "pwm_porting.h"
+#include "pinctrl.h"
+#define VIBRATOR_GPIOPPIN S_AGPIO_R2
+// #define VIBRATORPIN_MODE HAL_PIO_FUNC_PWMP1_M2
+#define VIBRATORPIN_MODE HAL_PIO_FUNC_PWMN1_M3
+
+#define TEST_TCXO_DELAY_1000MS 1000
+#define TEST_PARAM_FOR_PWM_10 10
+#define TEST_PARAM_FOR_PWM_200 200
+
+static pwm_channel_t channel = PWM_1;
+static pin_t pin = VIBRATOR_GPIOPPIN;
+static pin_mode_t mode = VIBRATORPIN_MODE;
+static uint32_t delay_ms = 500;
+static pwm_config_t cfg_repeat = { 100, 100, 0xFF, 0xFF, true };
+static uint32_t param_index = 0;
+static uint16_t repeat_times = 0;
+static errcode_t pwm_test_callback(uint8_t channel)
+{
+ PRINT("PWM number is %d, func of interrupt start. repeat_times %d\r\n", channel,repeat_times++);
+ uapi_pwm_isr(channel);
+ return ERRCODE_SUCC;
+}
+static uint8_t pwm_started = 0;
+static int test_pwm_repeat(int vibratorType)
+{
+
+ if (pwm_started == 1)
+ {
+ PRINT("PWM alredy started! skip start \r\n");
+ return -1;
+ }
+
+ if (channel >= PWM_MAX_NUMBER)
+ {
+ PRINT("Paremeter Error. PWM max number is 5. \r\n");
+ return -1;
+ }
+ pwm_started = 1;
+ repeat_times = 0;
+ uapi_pwm_init();
+ uapi_pin_set_mode(pin, mode);
+ PRINT("+++++++ pwm init success +++++++ \r\n");
+ uint32_t pwm_frequency = uapi_pwm_get_frequency(channel);
+ /* test for repeat, interrupt only be call when stop or close */
+ PRINT("+++++++ Start pwm repeat test +++++++ pwm_frequency %u\r\n",pwm_frequency);
+ // uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS);
+ // cfg_repeat.high_time = pwm_frequency/2;
+ // cfg_repeat.low_time = pwm_frequency/2;
+ uapi_pwm_open(channel, &cfg_repeat);
+ uapi_pwm_unregister_interrupt(channel);
+ uapi_pwm_register_interrupt(channel, pwm_test_callback);
+#if defined(CONFIG_PWM_USING_V151)
+ uapi_pwm_set_group(0, 1u << channel);
+ uapi_pwm_start(0);
+#else
+ uapi_pwm_start(channel);
+#endif
+ // uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS);
+ uapi_tcxo_delay_ms(delay_ms);
+
+ for (uint32_t test_times = 1; test_times <= vibratorType; test_times++) {
+
+ // uapi_pwm_check(channel)
+ PRINT("+++++++ pwm repeat interrupt +++++++ \r\n");
+ if (test_times == vibratorType) {
+ PRINT("+++++++ pwm repeat ready to trigger interrupt +++++++ \r\n");
+ uapi_pwm_close(channel);
+ break;
+ PRINT("+++++++ pwm repeat exit interrupt +++++++ \r\n");
+ }
+ uapi_tcxo_delay_ms(delay_ms);
+ }
+
+ uapi_pwm_close(channel);
+ // uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS);
+ uapi_tcxo_delay_ms(delay_ms);
+ uapi_pwm_deinit();
+ pwm_started = 0;
+ PRINT("+++++++ pwm stoped +++++++ \r\n");
+
+ return 0;
+}
+void g_VibratorFunc(uint8_t vibratorType , uint16_t delaytime)
+{
+
+ if(vibratorType <1 || vibratorType > 3)
+ {
+ PRINT("g_VibratorFunc vib times should in 1~3 \r\n",vibratorType);
+ }else{
+ PRINT("g_VibratorFunc vib %d times , delaytime %d\r\n",vibratorType , delaytime);
+ delay_ms = delaytime;
+ test_pwm_repeat(vibratorType);
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. \n
+ *
+ * Description: Button driver header file \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2023-02-24, Create file. \n
+ */
+#ifndef BUTTON_H
+#define BUTTON_H
+
+#include "hal_gpio.h"
+#include "soc_osal.h"
+#include "platform_core.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+/**
+ * vibtype 1 vib1 , 2 vib2, 3 vib3
+*/
+void g_VibratorFunc(uint8_t vibratorType , uint16_t delaytime);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
--- /dev/null
+
+// #include "vibrator.h"
+
+
+#include "at_cmd_api.h"
+#include "pm_control.h"
+#include "vibrator.h"
+#include "debug_print.h"
+
+#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
+#define VIBRATOR_MAX_ARGC 8
+#define VIBRATOR_MAX_ARGV_LEN 64
+
+#define VIBRATOR_SUCCESS 0
+#define VIBRATOR_FAILED (-1)
+
+static int ConvertCmdToParam(uint8_t *para, uint32_t paraLen,
+ uint8_t argv[VIBRATOR_MAX_ARGC][VIBRATOR_MAX_ARGV_LEN], uint32_t* argc)
+{
+ uint32_t pos = 0;
+ *argc = 0;
+
+ for (uint32_t i = 0; i < paraLen; i++) {
+ if ((para[i] == ' ' || para[i] == '\n') && pos != 0) {
+ argv[*argc][pos] = '\0';
+ *argc += 1;
+ pos = 0;
+ if (*argc >= VIBRATOR_MAX_ARGC) {
+ return VIBRATOR_FAILED;
+ }
+ } else {
+ argv[*argc][pos] = para[i];
+ pos++;
+ if (pos >= VIBRATOR_MAX_ARGV_LEN) {
+ return VIBRATOR_FAILED;
+ }
+ }
+ }
+ if (pos != 0) {
+ *argc += 1;
+ }
+
+ return VIBRATOR_SUCCESS;
+}
+
+
+static uint32_t vibrator_do_test(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+ UNUSED(strCommonCmd);
+ uint8_t argv[VIBRATOR_MAX_ARGC][VIBRATOR_MAX_ARGV_LEN] = { 0 };
+ uint32_t argc = 0;
+
+ int ret = ConvertCmdToParam(para, paraLen, argv, &argc);
+ if (ret != VIBRATOR_SUCCESS) {
+ PRINT("VIBRATORTEST ATCMD Convert Command Failed\n");
+ return ERRCODE_FAIL;
+ }
+
+ if (argc != 2) {
+ PRINT("VIBRATORTEST ATCMD Set Parameter Failed argc %d\n",argc);
+ return ERRCODE_FAIL;
+ }
+ uint8_t channel = (uint8_t)atoi((char*)argv[0]);
+ uint16_t delaytime = (uint16_t)atoi((char*)argv[1]);
+ g_VibratorFunc(channel,delaytime);
+ return ERRCODE_SUCC;
+}
+
+static const at_cmd_table_t g_vibrator_cmd[] = {
+ { (char *)"AT^VIBRATORTEST", vibrator_do_test, (char *)"1" },
+};
+
+at_cmd_table_t *get_vibrator_cmd_table(uint32_t *cmd_count)
+{
+ *cmd_count = ARRAY_COUNT(g_vibrator_cmd);
+ return (at_cmd_table_t *)g_vibrator_cmd;
+}
--- /dev/null
+/**
+ * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n
+ *
+ * Description: Provides at cmd register func \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2022-07-20, Create file. \n
+ */
+#ifndef VIBRATOR_AT_PROCESS_H
+#define VIBRATOR_AT_PROCESS_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include "errcode.h"
+#include "soc_osal.h"
+#include "at_cmd_api.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+at_cmd_table_t *get_vibrator_cmd_table(uint32_t *cmd_count);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
"key_status": "alive",
"structure_type": "btsrv_local_device_info_t",
"attributions": 1,
- "value": [[40,17,6,133,105, 89],0,0,["W","a","t","c","h","D","e","m","o",0]]
+ "value": [[40,17,6,133,105, 89],0,0,["W","a","t","c","h","S","o","a","r",0]]
},
"btsrv_paired_device_info":{
"key_id": "0x2102",
65576964, 1000, 679102459, 67108874, 327680, 655367, 2126009683,
654734439, 1, 0, 0, 0, 0, 0, 10551272, 655336, 4286447619, 64536,
500, 16384, 3277, 0, 66049, 0]]
+ },
+ "custom_key_serial_num":{
+ "key_id": "0x1010",
+ "key_status": "alive",
+ "structure_type": "custom_key_sn_t",
+ "attributions": 4,
+ "value": [32,
+ [0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0]]
}
}
}
uint32_t data[NV_AUDIO_VQE_PARAM_SIZE];
} audio_vqe_param_t;
+#define CUSTOM_KEY_SERIAL_NUM_SIZE 32
+typedef struct {
+ uint8_t size; /* 序列号长度 */
+ uint8_t sn[CUSTOM_KEY_SERIAL_NUM_SIZE]; /* 序列号数组 */
+} custom_key_sn_t;
+
#endif /* __COMMON_H__ */
/* user factory key_id [0x1000,0x2000) */
-
+#define NV_ID_CUSTOM_KEY_SERIAL_NUM 0x1010 /* 序列号 */
/* system normal key_id [0x2000,0x3000) */
#define NV_ID_SECURE_CONN 0x2001 /* secure connect */
#define NV_ID_AUDIO_VQE_PARAM 0x320C /* 3A params for VOIP scene, audio_vqe_param_t */
#define NV_ID_AUDIO_VQE_KWS_PARAM 0x320D /* 3A params for KWS scene, audio_vqe_param_t */
+
/* reserved key_id [0x4000,0xFFFF) */
#define NV_ID_SAMPLE_0 0x4000 /* Eg. */
#define NV_ID_SAMPLE_1 0x4001 /* Eg. */
#define NV_ID_SAMPLE_2 0x4002 /* Eg. */
#define NV_ID_SAMPLE_3 0x4003 /* Eg. */
#define NV_ID_SAMPLE_4 0x4004 /* Eg. */
+
+
#define NV_ID_FTM_CONFIG 0x4109
#define NV_ID_RESTORE_ENABLE 0xA000 /* NV restore factory region flag */
// create downlink AudioStreamIn
CapturerInputConfig captureConfig = {};
captureConfig.audioFormat = PCM;
- captureConfig.channelCount = 2;
+ captureConfig.channelCount = 1;
captureConfig.linkDir = AUDIO_DOWN_LINK;
- captureConfig.sampleRate = 16000;
+ captureConfig.sampleRate = 8000;
captureConfig.sessionID = context->sessionId;
captureConfig.streamType = AUDIO_STREAM_VOICE_CALL_VOLTE;
renderConfig.audioFormat = PCM;
renderConfig.channelCount = 1;
renderConfig.linkDir = AUDIO_UP_LINK;
- renderConfig.sampleRate = 16000;
+ renderConfig.sampleRate = 8000;
renderConfig.sessionID = context->sessionId;
renderConfig.streamType = AUDIO_STREAM_VOICE_CALL_VOLTE;
if (ret != 0) {
MEDIA_ERR_LOG("set sco out device connect failed");
}
-
+#error no local voice call
ret = g_amInstance.SetDeviceConnectionState(IN_MODEM_HEADSET, AUDIO_DEVICE_CONNECTED);
if (ret != 0) {
MEDIA_ERR_LOG("set modem headset in device connect failed");
#define AT_CMD_BUFSIZE 256
#define AT_CMD_NAME_MAX_LEN 32
#define AT_CMD_END_MARK_LEN 2
-#define AT_CMD_MODULE_MAX_NUM 10
+#define AT_CMD_MODULE_MAX_NUM 50
#define AT_CMD_MSG_COUNT 16
#define OFF_TWO 2
add_subdirectory_with_alias_if_exist(third_party/icu ${PROJECT_BINARY_DIR}/icu)
add_subdirectory_with_alias_if_exist(third_party/harfbuzz ${PROJECT_BINARY_DIR}/harfbuzz)
endif()
+if (DEFINES MATCHES "ENABLE_SLIP")
+ set(ROOTDIR ${ROOT_DIR})
+ add_subdirectory_with_alias_if_exist(third_party/lwip ${PROJECT_BINARY_DIR}/lwip)
+endif()
add_subdirectory_with_alias_if_exist(base/startup/bootstrap_lite ${PROJECT_BINARY_DIR}/ohos/bootstrap)
add_subdirectory_with_alias_if_exist(base/startup/syspara_lite ${PROJECT_BINARY_DIR}/ohos/syspara)
+
+# Target for package generation
+# add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
+# add_dependencies(dist lwipdocs)
+
+#===============================================================================
+# @brief cmake file
+# Copyright (c) CompanyNameMagicTag 2022-2022. All rights reserved.
+#===============================================================================
cmake_minimum_required(VERSION 3.7)
-project(lwIP)
+set(COMPONENT_NAME "lwIP")
+
+set(PROJECT_ROOT_DIR ${ROOTDIR})
+set(LWIP_ROOT_DIR ${PROJECT_ROOT_DIR}/open_source/openharmony/third_party/lwip)
set(LWIP_DIR ${CMAKE_CURRENT_SOURCE_DIR})
-include(src/Filelists.cmake)
+# message(STATUS "=======LWIP PROJECT_ROOT_DIR " ${PROJECT_ROOT_DIR})
+include(${LWIP_ROOT_DIR}/src/Filelists.cmake)
+
+
+
+
+# project(lwIP)
+# return_if_not_build()
+
+
# Package generation
-set(CPACK_SOURCE_GENERATOR "ZIP")
-set(CPACK_SOURCE_PACKAGE_DESCRIPTION_SUMMARY "lwIP lightweight IP stack")
-set(CPACK_PACKAGE_VERSION_MAJOR "${LWIP_VERSION_MAJOR}")
-set(CPACK_PACKAGE_VERSION_MINOR "${LWIP_VERSION_MINOR}")
-set(CPACK_PACKAGE_VERSION_PATCH "${LWIP_VERSION_REVISION}")
-set(CPACK_SOURCE_IGNORE_FILES "/build/;${CPACK_SOURCE_IGNORE_FILES};.git")
-set(CPACK_SOURCE_PACKAGE_FILE_NAME "lwip-${LWIP_VERSION_MAJOR}.${LWIP_VERSION_MINOR}.${LWIP_VERSION_REVISION}")
-include(CPack)
+# set(CPACK_SOURCE_GENERATOR "ZIP")
+# set(CPACK_SOURCE_PACKAGE_DESCRIPTION_SUMMARY "lwIP lightweight IP stack")
+# set(CPACK_PACKAGE_VERSION_MAJOR "${LWIP_VERSION_MAJOR}")
+# set(CPACK_PACKAGE_VERSION_MINOR "${LWIP_VERSION_MINOR}")
+# set(CPACK_PACKAGE_VERSION_PATCH "${LWIP_VERSION_REVISION}")
+# set(CPACK_SOURCE_IGNORE_FILES "/build/;${CPACK_SOURCE_IGNORE_FILES};.git")
+# set(CPACK_SOURCE_PACKAGE_FILE_NAME "lwip-${LWIP_VERSION_MAJOR}.${LWIP_VERSION_MINOR}.${LWIP_VERSION_REVISION}")
+# include(CPack)
+set(PORT_SOURCES
+ ${LWIP_ROOT_DIR}/port/LiteOS/sys_arch.c
-# Target for package generation
-add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
-add_dependencies(dist lwipdocs)
+)
+
+set(SOURCES
+ ${lwipcore_SRCS}
+ ${lwipcore4_SRCS}
+ ${lwipapi_SRCS}
+ ${lwipnetif_SRCS}
+ ${lwiphttp_SRCS}
+ ${lwipsntp_SRCS}
+ ${lwipmbedtls_SRCS}
+ ${lwiphttp_SRCS}
+ ${lwiphttp_SRCS}
+ ${PORT_SOURCES}
+)
+
+set(PUBLIC_HEADER
+ ${LWIP_ROOT_DIR}/src/include
+ # ${LWIP_ROOT_DIR}/test/unit
+ ${LWIP_ROOT_DIR}/port/include
+)
+
+set(PRIVATE_HEADER
+)
+
+set(CCDEFINES ${defines})
+set(PRIVATE_DEFINES
+ ${CCDEFINES}
+)
+
+set(PUBLIC_DEFINES
+)
+
+# use this when you want to add ccflags like -include xxx
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+ # -std=c++11
+ -Wno-error
+ -Wno-unused-parameter
+ -fno-exceptions
+ -fno-unwind-tables
+ -fno-asynchronous-unwind-tables
+ -Wno-undef
+ -Wno-bitwise-op-parentheses
+ -Wno-shift-op-parentheses
+ -Wno-sometimes-uninitialized
+)
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+build_component()
+
+install_sdk(${CMAKE_CURRENT_SOURCE_DIR} "*")
--- /dev/null
+/**
+* @file
+* Ethernet Interface Skeleton
+*
+*/
+
+/*
+* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+* 3. The name of the author may not be used to endorse or promote products
+* derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+* OF SUCH DAMAGE.
+*
+* This file is part of the lwIP TCP/IP stack.
+*
+* Author: Adam Dunkels <adam@sics.se>
+*
+*/
+
+/*
+* This file is a skeleton for developing Ethernet network interface
+* drivers for lwIP. Add code to the low_level functions and do a
+* search-and-replace for the word "ethernetif" to replace it with
+* something that better describes your network interface.
+*/
+
+#include "lwip/opt.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/pbuf.h"
+#include "lwip/timers.h"
+#include "netif/etharp.h"
+#include "err.h"
+#include "ethernetif.h"
+#include "includes.h"
+#include "stm32f429_eth.h"
+#include "lwipopts/netconf.h"
+#include <string.h>
+#include "los_base.h"
+
+#define netifINTERFACE_TASK_STACK_SIZE ( 512u )
+#define netifINTERFACE_TASK_PRIORITY ( 4u )
+
+/* Define those to better describe your network interface. */
+#define IFNAME0 'w'
+#define IFNAME1 'f'
+
+
+static struct netif *s_pxNetIf = NULL;
+
+
+/* Ethernet Rx & Tx DMA Descriptors */
+extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB];
+
+/* Ethernet Receive buffers */
+extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE];
+
+/* Ethernet Transmit buffers */
+extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE];
+
+/* Global pointers to track current transmit and receive descriptors */
+extern ETH_DMADESCTypeDef *DMATxDescToSet;
+extern ETH_DMADESCTypeDef *DMARxDescToGet;
+
+/* Global pointer for last received frame infos */
+extern ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos;
+
+
+static void ethernetif_input( void * pvParameters );
+static void arp_timer(void *arg);
+
+
+/**
+* In this function, the hardware should be initialized.
+* Called from ethernetif_init().
+*
+* @param netif the already initialized lwip network interface structure
+* for this ethernetif
+*/
+static void low_level_init(struct netif *netif)
+{
+ uint32_t i;
+
+ /* set netif MAC hardware address length */
+ netif->hwaddr_len = ETHARP_HWADDR_LEN;
+
+ /* set netif MAC hardware address */
+ netif->hwaddr[0] = MAC_ADDR0;
+ netif->hwaddr[1] = MAC_ADDR1;
+ netif->hwaddr[2] = MAC_ADDR2;
+ netif->hwaddr[3] = MAC_ADDR3;
+ netif->hwaddr[4] = MAC_ADDR4;
+ netif->hwaddr[5] = MAC_ADDR5;
+
+ /* set netif maximum transfer unit */
+ netif->mtu = 1500;
+
+ /* Accept broadcast address and ARP traffic */
+ netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
+
+ s_pxNetIf =netif;
+
+ /* initialize MAC address in ethernet MAC */
+ ETH_MACAddressConfig(ETH_MAC_Address0, netif->hwaddr);
+
+ /* Initialize Tx Descriptors list: Chain Mode */
+ ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
+ /* Initialize Rx Descriptors list: Chain Mode */
+ ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
+
+ /* Enable Ethernet Rx interrrupt */
+ {
+ for(i=0; i<ETH_RXBUFNB; i++)
+ {
+ ETH_DMARxDescReceiveITConfig(&DMARxDscrTab[i], ENABLE);
+ }
+ }
+
+#ifdef CHECKSUM_BY_HARDWARE
+ /* Enable the checksum insertion for the Tx frames */
+ {
+ for(i=0; i<ETH_TXBUFNB; i++)
+ {
+ ETH_DMATxDescChecksumInsertionConfig(&DMATxDscrTab[i], ETH_DMATxDesc_ChecksumTCPUDPICMPFull);
+ }
+ }
+#endif
+
+ /* create the task that handles the ETH_MAC */
+ sys_thread_new((const char*)"Eth_if",ethernetif_input,netif,netifINTERFACE_TASK_STACK_SIZE,netifINTERFACE_TASK_PRIORITY);
+
+ /* Enable MAC and DMA transmission and reception */
+ ETH_Start();
+}
+
+
+/**
+* This function should do the actual transmission of the packet. The packet is
+* contained in the pbuf that is passed to the function. This pbuf
+* might be chained.
+*
+* @param netif the lwip network interface structure for this ethernetif
+* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
+* @return ERR_OK if the packet could be sent
+* an err_t value if the packet couldn't be sent
+*
+* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
+* strange results. You might consider waiting for space in the DMA queue
+* to become availale since the stack doesn't retry to send a packet
+* dropped because of memory failure (except for the TCP timers).
+*/
+
+static err_t low_level_output(struct netif *netif, struct pbuf *p)
+{
+// err_t errval;
+ struct pbuf *q;
+ u8 *buffer ;
+ __IO ETH_DMADESCTypeDef *DmaTxDesc;
+ uint16_t framelength = 0;
+ uint32_t bufferoffset = 0;
+ uint32_t byteslefttocopy = 0;
+ uint32_t payloadoffset = 0;
+
+ SYS_ARCH_DECL_PROTECT(sr);
+ /* Interrupts are disabled through this whole thing to support multi-threading
+ transmit calls. Also this function might be called from an ISR. */
+ SYS_ARCH_PROTECT(sr);
+
+ DmaTxDesc = DMATxDescToSet;
+ buffer = (u8 *)(DmaTxDesc->Buffer1Addr);
+ bufferoffset = 0;
+
+ for(q = p; q != NULL; q = q->next)
+ {
+ if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET)
+ {
+// errval = ERR_BUF;
+ goto error;
+ }
+
+ /* Get bytes in current lwIP buffer */
+ byteslefttocopy = q->len;
+ payloadoffset = 0;
+
+ /* Check if the length of data to copy is bigger than Tx buffer size*/
+ while( (byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE )
+ {
+ /* Copy data to Tx buffer*/
+ memcpy( (u8_t*)((u8_t*)buffer + bufferoffset), (u8_t*)((u8_t*)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset) );
+
+ /* Point to next descriptor */
+ DmaTxDesc = (ETH_DMADESCTypeDef *)(DmaTxDesc->Buffer2NextDescAddr);
+
+ /* Check if the buffer is available */
+ if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET)
+ {
+// errval = ERR_USE;
+ goto error;
+ }
+
+ buffer = (u8 *)(DmaTxDesc->Buffer1Addr);
+
+ byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset);
+ payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset);
+ framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset);
+ bufferoffset = 0;
+ }
+
+ /* Copy the remaining bytes */
+ memcpy( (u8_t*)((u8_t*)buffer + bufferoffset), (u8_t*)((u8_t*)q->payload + payloadoffset), byteslefttocopy );
+ bufferoffset = bufferoffset + byteslefttocopy;
+ framelength = framelength + byteslefttocopy;
+ }
+
+ /* Prepare transmit descriptors to give to DMA*/
+ ETH_Prepare_Transmit_Descriptors(framelength);
+// errval = ERR_OK;
+ /* Give semaphore and exit */
+ error:
+
+// /* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */
+// if ((ETH->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET)
+// {
+// /* Clear TUS ETHERNET DMA flag */
+// ETH->DMASR = ETH_DMASR_TUS;
+
+// /* Resume DMA transmission*/
+// ETH->DMATPDR = 0;
+// }
+// return errval;
+ SYS_ARCH_UNPROTECT(sr);
+ return ERR_OK;
+}
+
+/**
+* Should allocate a pbuf and transfer the bytes of the incoming
+* packet from the interface into the pbuf.
+*
+* @param netif the lwip network interface structure for this ethernetif
+* @return a pbuf filled with the received packet (including MAC header)
+* NULL on memory error
+*/
+static struct pbuf * low_level_input(struct netif *netif)
+{
+ struct pbuf *p= NULL, *q;
+ u32_t len;
+ FrameTypeDef frame;
+ u8 *buffer;
+ __IO ETH_DMADESCTypeDef *DMARxDesc;
+ uint32_t bufferoffset = 0;
+ uint32_t payloadoffset = 0;
+ uint32_t byteslefttocopy = 0;
+ uint32_t i=0;
+
+ /* get received frame */
+ frame = ETH_Get_Received_Frame_interrupt();
+
+ /* Obtain the size of the packet and put it into the "len" variable. */
+ len = frame.length;
+ buffer = (u8 *)frame.buffer;
+
+ if (len > 0)
+ {
+ /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
+ p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
+ }
+
+ if (p != NULL)
+ {
+ DMARxDesc = frame.descriptor;
+ bufferoffset = 0;
+ for(q = p; q != NULL; q = q->next)
+ {
+ byteslefttocopy = q->len;
+ payloadoffset = 0;
+
+ /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/
+ while( (byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE )
+ {
+ /* Copy data to pbuf*/
+ memcpy( (u8_t*)((u8_t*)q->payload + payloadoffset), (u8_t*)((u8_t*)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset));
+
+ /* Point to next descriptor */
+ DMARxDesc = (ETH_DMADESCTypeDef *)(DMARxDesc->Buffer2NextDescAddr);
+ buffer = (unsigned char *)(DMARxDesc->Buffer1Addr);
+
+ byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset);
+ payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset);
+ bufferoffset = 0;
+ }
+
+ /* Copy remaining data in pbuf */
+ memcpy( (u8_t*)((u8_t*)q->payload + payloadoffset), (u8_t*)((u8_t*)buffer + bufferoffset), byteslefttocopy);
+ bufferoffset = bufferoffset + byteslefttocopy;
+ }
+ }
+
+ /* Release descriptors to DMA */
+ DMARxDesc =frame.descriptor;
+
+ /* Set Own bit in Rx descriptors: gives the buffers back to DMA */
+ for (i=0; i<DMA_RX_FRAME_infos->Seg_Count; i++)
+ {
+ DMARxDesc->Status = ETH_DMARxDesc_OWN;
+ DMARxDesc = (ETH_DMADESCTypeDef *)(DMARxDesc->Buffer2NextDescAddr);
+ }
+
+ /* Clear Segment_Count */
+ DMA_RX_FRAME_infos->Seg_Count =0;
+
+ /* When Rx Buffer unavailable flag is set: clear it and resume reception */
+ if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)
+ {
+ /* Clear RBUS ETHERNET DMA flag */
+ ETH->DMASR = ETH_DMASR_RBUS;
+ /* Resume DMA reception */
+ ETH->DMARPDR = 0;
+ }
+ return p;
+}
+
+
+/**
+* This function is the ethernetif_input task, it is processed when a packet
+* is ready to be read from the interface. It uses the function low_level_input()
+* that should handle the actual reception of bytes from the network
+* interface. Then the type of the received packet is determined and
+* the appropriate input function is called.
+*
+* @param netif the lwip network interface structure for this ethernetif
+*/
+void ethernetif_input( void * pvParameters )
+{
+ struct pbuf *p;
+ err_t err;
+
+ /* move received packet into a new pbuf */
+ while (1)
+ {
+ SYS_ARCH_DECL_PROTECT(sr);
+ SYS_ARCH_PROTECT(sr);
+ p = low_level_input(s_pxNetIf);
+ SYS_ARCH_UNPROTECT(sr);
+ if (p == NULL)
+ continue;
+ err = s_pxNetIf->input(p, s_pxNetIf);
+ if (err != ERR_OK){
+ LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
+ pbuf_free(p);
+ p = NULL;
+ }
+ /*sleep 5 ms*/
+ LOS_Msleep(5);
+ }
+}
+
+/**
+* Should be called at the beginning of the program to set up the
+* network interface. It calls the function low_level_init() to do the
+* actual setup of the hardware.
+*
+* This function should be passed as a parameter to netif_add().
+*
+* @param netif the lwip network interface structure for this ethernetif
+* @return ERR_OK if the loopif is initialized
+* ERR_MEM if private data couldn't be allocated
+* any other err_t on error
+*/
+err_t ethernetif_init(struct netif *netif)
+{
+// ETH_BSP_Config();
+
+ LWIP_ASSERT("netif != NULL", (netif != NULL));
+
+#if LWIP_NETIF_HOSTNAME
+ /* Initialize interface hostname */
+ netif->hostname = "lwip";
+#endif /* LWIP_NETIF_HOSTNAME */
+
+ netif->name[0] = IFNAME0;
+ netif->name[1] = IFNAME1;
+
+ netif->output = etharp_output;
+ netif->linkoutput = low_level_output;
+
+
+ /* initialize the hardware */
+ low_level_init(netif);
+
+ etharp_init();
+ sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
+
+ return ERR_OK;
+}
+
+
+static void arp_timer(void *arg)
+{
+ etharp_tmr();
+ sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
+}
+
--- /dev/null
+#ifndef __ETHERNETIF_H__
+#define __ETHERNETIF_H__
+
+
+#include "lwip/err.h"
+#include "lwip/netif.h"
+
+err_t ethernetif_init(struct netif *netif);
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+ //============================================================================
+ //Ҷ���Ƽ� 2018-05-01 ��д
+ //============================================================================
+#define SYS_ARCH_GLOBALS
+
+/* lwIP includes. */
+#include "lwip/debug.h"
+#include "lwip/def.h"
+#include "lwip/sys.h"
+#include "lwip/mem.h"
+#include "lwip/stats.h"
+#include "lwip/err.h"
+// #include "includes.h"
+#include "arch/sys_arch.h"
+#include "cmsis_os.h"
+#include "los_sem.h"
+
+#define SYS_THREAD_MAX 6
+static u16_t s_nextthread = 0;
+
+/*----------------------------------------------------------------------------*/
+/* DEFINITIONS */
+/*----------------------------------------------------------------------------*/
+#define LWIP_ARCH_TICK_PER_MS 1000/OS_CFG_TICK_RATE_HZ
+
+/*----------------------------------------------------------------------------*/
+/* VARIABLES */
+/*----------------------------------------------------------------------------*/
+
+u32_t sys_now()
+{
+ return LOS_TickCountGet();
+}
+//=====================================================================================
+/*-----------------------------------------------------------------------------------*/
+//Creates an empty mailbox.
+err_t sys_mbox_new(sys_mbox_t *mbox, int size)
+{
+ osMessageQueueAttr_t queue_def;
+ (void ) size;
+ *mbox = osMessageQueueNew(MAX_QUEUES, MAX_QUEUE_ENTRIES,&queue_def);
+
+#if SYS_STATS
+ ++lwip_stats.sys.mbox.used;
+ if(lwip_stats.sys.mbox.max < lwip_stats.sys.mbox.used){
+ lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used;
+ }
+#endif /* SYS_STATS */
+ if (*mbox == NULL){
+ return ERR_MEM;
+ }
+
+ return ERR_OK;
+}
+
+/*-----------------------------------------------------------------------------------*/
+/*
+ Deallocates a mailbox. If there are messages still present in the
+ mailbox when the mailbox is deallocated, it is an indication of a
+ programming error in lwIP and the developer should be notified.
+*/
+void sys_mbox_free(sys_mbox_t *mbox)
+{
+ if(osOK != osMessageQueueDelete(*mbox))
+ {
+#if SYS_STATS
+ lwip_stats.sys.mbox.err++;
+#endif /* SYS_STATS */
+ }
+#if SYS_STATS
+ --lwip_stats.sys.mbox.used;
+#endif /* SYS_STATS */
+}
+
+/*-----------------------------------------------------------------------------------*/
+// Posts the "msg" to the mailbox.
+void sys_mbox_post(sys_mbox_t *mbox, void *data)
+{
+ while (osOK != osMessageQueuePut(*mbox, data,0,portMAX_DELAY))
+ {
+ }
+}
+
+/*-----------------------------------------------------------------------------------*/
+// Try to post the "msg" to the mailbox.
+err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
+{
+ err_t result;
+ osStatus_t ret;
+ ret = osMessageQueuePut(*mbox, msg, 0,0);
+ if( osOK == ret)
+ {
+ result = ERR_OK;
+ }
+ else
+ {
+ result = ERR_MEM;
+#if SYS_STATS
+ lwip_stats.sys.mbox.err++;
+#endif /* SYS_STATS */
+ }
+ return result;
+}
+
+/*-----------------------------------------------------------------------------------*/
+/*
+ Blocks the thread until a message arrives in the mailbox, but does
+ not block the thread longer than "timeout" milliseconds (similar to
+ the sys_arch_sem_wait() function). The "msg" argument is a result
+ parameter that is set by the function (i.e., by doing "*msg =
+ ptr"). The "msg" parameter maybe NULL to indicate that the message
+ should be dropped.
+
+ The return values are the same as for the sys_arch_sem_wait() function:
+ Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
+ timeout.
+
+ Note that a function with a similar name, sys_mbox_fetch(), is
+ implemented by lwIP.
+*/
+u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
+{
+ void *dummyptr;
+ UINT64 StartTime, EndTime, Elapsed;
+ osStatus_t ret;
+
+ StartTime = LOS_TickCountGet();
+
+ if( msg == NULL ){
+ msg = &dummyptr;
+ }
+
+ if( timeout != 0 ){
+ ret = osMessageQueueGet(*mbox, *msg,NULL,timeout);
+ if ( osOK == ret ){
+ EndTime = LOS_TickCountGet();
+ Elapsed = (EndTime - StartTime);
+ return ( Elapsed );
+ }
+ // timed out blocking for message
+ else{
+ *msg = NULL;
+ return SYS_ARCH_TIMEOUT;
+ }
+ }
+ // block forever for a message.
+ else
+ {
+ ret = osMessageQueueGet(*mbox, *msg,NULL,portMAX_DELAY);
+ while(osOK == ret )
+ {
+ ret = osMessageQueueGet(*mbox, *msg,NULL,portMAX_DELAY);
+ } // time is arbitrary
+ EndTime = LOS_TickCountGet();
+ Elapsed = EndTime - StartTime;
+ return ( Elapsed ); // return time blocked TODO test
+ }
+}
+
+/*-----------------------------------------------------------------------------------*/
+/*
+ Similar to sys_arch_mbox_fetch, but if message is not ready immediately, we'll
+ return with SYS_MBOX_EMPTY. On success, 0 is returned.
+*/
+u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
+{
+ void *dummyptr;
+ osStatus_t ret;
+
+ if( msg == NULL )
+ {
+ msg = &dummyptr;
+ }
+ ret = osMessageQueueGet(*mbox, *msg,NULL,0);
+ if ( osOK == ret ){
+ return ERR_OK;
+ }
+ else
+ {
+ return SYS_MBOX_EMPTY;
+ }
+}
+
+
+static osPriority_t get_prio(int prio)
+{
+ osPriority_t ret = osPriorityNormal;
+ if (prio >= 7)
+ {
+ ret = osPriorityRealtime;
+ }
+ else if(prio == 6)
+ {
+ ret = osPriorityHigh;
+ }
+ else if(prio == 5)
+ {
+ ret = osPriorityAboveNormal;
+ }
+ else if(prio == 4)
+ {
+ ret = osPriorityNormal;
+ }
+ else if(prio == 3)
+ {
+ ret = osPriorityBelowNormal;
+ }
+ else if(prio == 2)
+ {
+ ret = osPriorityLow;
+ }
+ else if(prio == 1)
+ {
+ ret = osPriorityIdle;
+ }
+ else
+ {
+ ret = osPriorityNormal;
+ }
+ return ret;
+}
+
+/*
+ Starts a new thread with priority "prio" that will begin its execution in the
+ function "thread()". The "arg" argument will be passed as an argument to the
+ thread() function. The id of the new thread is returned. Both the id and
+ the priority are system dependent.
+*/
+sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio)
+{
+ osThreadId_t id;
+ osThreadAttr_t thread_def;
+
+ if ( s_nextthread < SYS_THREAD_MAX )
+ {
+ thread_def.name = name;
+ thread_def.priority = get_prio(prio);
+ thread_def.stack_size = stacksize;
+ id = osThreadNew(thread, arg, &thread_def);
+ if (NULL != id)
+ {
+ return id;
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+//=====================================================================================
+
+/*----------------------------------------------------------------------------------*/
+int sys_mbox_valid(sys_mbox_t *mbox)
+{
+ if (*mbox == SYS_MBOX_NULL){
+ return 0;
+ }
+ else{
+ return 1;
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+void sys_mbox_set_invalid(sys_mbox_t *mbox)
+{
+ *mbox = SYS_MBOX_NULL;
+}
+
+/*-----------------------------------------------------------------------------------*/
+// Creates a new semaphore. The "count" argument specifies
+// the initial state of the semaphore.
+err_t sys_sem_new(sys_sem_t *sem, u8_t count)
+{
+ u32_t ret;
+ ret = LOS_SemCreate(count,(UINT32 *)sem);
+ if(ret != LOS_OK){
+#if SYS_STATS
+ ++lwip_stats.sys.sem.err;
+#endif /* SYS_STATS */
+ return ERR_MEM;
+ }
+ // Means it can't be taken
+ if(count == 0){
+ ret = LOS_SemPend((UINT32)*sem, 1);
+ }
+
+#if SYS_STATS
+ ++lwip_stats.sys.sem.used;
+ if (lwip_stats.sys.sem.max < lwip_stats.sys.sem.used){
+ lwip_stats.sys.sem.max = lwip_stats.sys.sem.used;
+ }
+#endif /* SYS_STATS */
+
+ return ERR_OK;
+}
+
+/*-----------------------------------------------------------------------------------*/
+/*
+ Blocks the thread while waiting for the semaphore to be
+ signaled. If the "timeout" argument is non-zero, the thread should
+ only be blocked for the specified time (measured in
+ milliseconds).
+
+ If the timeout argument is non-zero, the return value is the number of
+ milliseconds spent waiting for the semaphore to be signaled. If the
+ semaphore wasn't signaled within the specified time, the return value is
+ SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
+ (i.e., it was already signaled), the function may return zero.
+
+ Notice that lwIP implements a function with a similar name,
+ sys_sem_wait(), that uses the sys_arch_sem_wait() function.
+*/
+u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
+{
+ UINT64 StartTime, EndTime, Elapsed;
+ u32_t ret;
+ StartTime = LOS_TickCountGet();
+
+ if(timeout != 0)
+ {
+ ret = LOS_SemPend((UINT32)*sem, timeout);
+ if(LOS_OK == ret)
+ {
+ EndTime = LOS_TickCountGet();
+ Elapsed = EndTime - StartTime;
+ return (Elapsed); // return time blocked TODO test
+ }
+ else
+ {
+ return SYS_ARCH_TIMEOUT;
+ }
+ }
+ // must block without a timeout
+ else
+ {
+ while(LOS_OK != LOS_SemPend((UINT32)*sem, LOS_WAIT_FOREVER))
+ {
+ }
+ EndTime = LOS_TickCountGet();
+ Elapsed = EndTime - StartTime;
+ return ( Elapsed ); // return time blocked
+ }
+}
+
+/*-----------------------------------------------------------------------------------*/
+// Signals a semaphore
+void sys_sem_signal(sys_sem_t *sem)
+{
+ LOS_SemPost((UINT32)*sem);
+}
+
+/*-----------------------------------------------------------------------------------*/
+// Deallocates a semaphore
+void sys_sem_free(sys_sem_t *sem)
+{
+#if SYS_STATS
+ --lwip_stats.sys.sem.used;
+#endif /* SYS_STATS */
+ LOS_SemDelete((UINT32)*sem);
+}
+/*-----------------------------------------------------------------------------------*/
+int sys_sem_valid(sys_sem_t *sem)
+{
+ if (*sem == SYS_SEM_NULL){
+ return 0;
+ }
+ else{
+ return 1;
+ }
+}
+
+/*-----------------------------------------------------------------------------------*/
+void sys_sem_set_invalid(sys_sem_t *sem)
+{
+ *sem = SYS_SEM_NULL;
+}
+
+/*-----------------------------------------------------------------------------------*/
+// Initialize sys arch
+void sys_init(void)
+{
+ // keep track of how many threads have been created
+ s_nextthread = 0;
+}
+/*-----------------------------------------------------------------------------------*/
+ /* Mutexes*/
+/*-----------------------------------------------------------------------------------*/
+/*-----------------------------------------------------------------------------------*/
+#if LWIP_COMPAT_MUTEX == 0
+/* Create a new mutex*/
+err_t sys_mutex_new(sys_mutex_t *mutex)
+{
+ osMutexDef_t mutex_def;
+ //*mutex = xSemaphoreCreateMutex();
+ *mutex = osMutexCreate (&mutex_def);
+ if(*mutex == NULL){
+#if SYS_STATS
+ ++lwip_stats.sys.mutex.err;
+#endif /* SYS_STATS */
+ return ERR_MEM;
+ }
+
+#if SYS_STATS
+ ++lwip_stats.sys.mutex.used;
+ if(lwip_stats.sys.mutex.max < lwip_stats.sys.mutex.used){
+ lwip_stats.sys.mutex.max = lwip_stats.sys.mutex.used;
+ }
+#endif /* SYS_STATS */
+ return ERR_OK;
+}
+/*-----------------------------------------------------------------------------------*/
+/* Deallocate a mutex*/
+void sys_mutex_free(sys_mutex_t *mutex)
+{
+#if SYS_STATS
+ --lwip_stats.sys.mutex.used;
+#endif /* SYS_STATS */
+ osMutexDelete(*mutex);
+}
+/*-----------------------------------------------------------------------------------*/
+/* Lock a mutex*/
+void sys_mutex_lock(sys_mutex_t *mutex)
+{
+ osMutexWait(*mutex, portMAX_DELAY);
+}
+
+/*-----------------------------------------------------------------------------------*/
+/* Unlock a mutex*/
+void sys_mutex_unlock(sys_mutex_t *mutex)
+{
+ osMutexRelease(*mutex);
+}
+#endif /*LWIP_COMPAT_MUTEX*/
+
+/*-----------------------------------------------------------------------------------*/
+// TODO
+/*-----------------------------------------------------------------------------------*/
+/*
+ This optional function does a "fast" critical region protection and returns
+ the previous protection level. This function is only called during very short
+ critical regions. An embedded system which supports ISR-based drivers might
+ want to implement this function by disabling interrupts. Task-based systems
+ might want to implement this by using a mutex or disabling tasking. This
+ function should support recursive calls from the same task or interrupt. In
+ other words, sys_arch_protect() could be called while already protected. In
+ that case the return value indicates that it is already protected.
+
+ sys_arch_protect() is only required if your port is supporting an operating
+ system.
+*/
+sys_prot_t sys_arch_protect(void)
+{
+ sys_prot_t ret;
+ ret = LOS_IntLock();
+ return ret;
+}
+
+/*
+ This optional function does a "fast" set of critical region protection to the
+ value specified by pval. See the documentation for sys_arch_protect() for
+ more information. This function is only required if your port is supporting
+ an operating system.
+*/
+void sys_arch_unprotect(sys_prot_t pval)
+{
+ LOS_IntRestore(pval);
+}
+
+/*
+ * Prints an assertion messages and aborts execution.
+ */
+void sys_assert( const char *msg )
+{
+ ( void ) msg;
+ LOS_IntLock();
+ for(;;);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __SYS_RTXC_H__
+#define __SYS_RTXC_H__
+
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+#define SYS_MBOX_NULL (xQueueHandle)0
+#define SYS_SEM_NULL (xSemaphoreHandle)0
+#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE
+
+typedef xSemaphoreHandle sys_sem_t;
+typedef xQueueHandle sys_mbox_t;
+typedef xTaskHandle sys_thread_t;
+
+typedef struct _sys_arch_state_t
+{
+ // Task creation data.
+ char cTaskName[configMAX_TASK_NAME_LEN];
+ unsigned short nStackDepth;
+ unsigned short nTaskCount;
+} sys_arch_state_t;
+
+
+
+//extern sys_arch_state_t s_sys_arch_state;
+
+//void sys_set_default_state();
+//void sys_set_state(signed char *pTaskName, unsigned short nStackSize);
+
+/* Message queue constants. */
+#define archMESG_QUEUE_LENGTH ( 6 )
+#endif /* __SYS_RTXC_H__ */
+
--- /dev/null
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#if defined(__IAR_SYSTEMS_ICC__)
+#pragma pack(1)
+#endif
+
--- /dev/null
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __CC_H__
+#define __CC_H__
+
+#include "arch/cpu.h"
+
+typedef unsigned char u8_t;
+typedef signed char s8_t;
+typedef unsigned short u16_t;
+typedef signed short s16_t;
+typedef unsigned long u32_t;
+typedef signed long s32_t;
+typedef u32_t mem_ptr_t;
+
+//typedef int sys_prot_t;
+//#define U16_F "hu"
+//#define S16_F "d"
+//#define X16_F "hx"
+//#define U32_F "u"
+//#define S32_F "d"
+//#define X32_F "x"
+//#define SZT_F "uz"
+
+#define U16_F "4d"
+#define S16_F "4d"
+#define X16_F "4x"
+#define U32_F "8ld"
+#define S32_F "8ld"
+#define X32_F "8lx"
+
+/* define compiler specific symbols */
+#if defined (__ICCARM__)
+
+#define PACK_STRUCT_BEGIN
+#define PACK_STRUCT_STRUCT
+#define PACK_STRUCT_END
+#define PACK_STRUCT_FIELD(x) x
+#define PACK_STRUCT_USE_INCLUDES
+
+#elif defined (__CC_ARM)
+
+#define PACK_STRUCT_BEGIN __packed
+#define PACK_STRUCT_STRUCT
+#define PACK_STRUCT_END
+#define PACK_STRUCT_FIELD(x) x
+
+#elif defined (__GNUC__)
+
+#define PACK_STRUCT_BEGIN
+#define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
+#define PACK_STRUCT_END
+#define PACK_STRUCT_FIELD(x) x
+
+#elif defined (__TASKING__)
+
+#define PACK_STRUCT_BEGIN
+#define PACK_STRUCT_STRUCT
+#define PACK_STRUCT_END
+#define PACK_STRUCT_FIELD(x) x
+
+#endif
+
+//�궨��
+#define LWIP_PLATFORM_ASSERT(x) do { printf("Assertion \"%s\" failed at line %d in %s\n", \
+ x, __LINE__, __FILE__);} while(0)
+
+#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
+ printf("Assertion \"%s\" failed at line %d in %s\n", message, __LINE__, __FILE__); \
+ fflush(NULL);handler;} } while(0)
+
+#endif /* __CC_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#if defined(__IAR_SYSTEMS_ICC__)
+#pragma pack()
+#endif
+
--- /dev/null
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __ARCH_INIT_H__
+#define __ARCH_INIT_H__
+
+#define TCPIP_INIT_DONE(arg) tcpip_init_done(arg)
+
+void tcpip_init_done(void *);
+int wait_for_tcpip_init(void);
+
+#endif /* __ARCH_INIT_H__ */
+
+
+
+
--- /dev/null
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LIB_H__
+#define __LIB_H__
+
+#include <string.h>
+
+
+#endif /* __LIB_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __PERF_H__
+#define __PERF_H__
+
+#define PERF_START /* null definition */
+#define PERF_STOP(x) /* null definition */
+
+#endif /* __PERF_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __SYS_RTXC_H__
+#define __SYS_RTXC_H__
+
+// #include "includes.h"
+#include "arch/cc.h"
+
+#ifdef SYS_ARCH_GLOBALS
+#define SYS_ARCH_EXT
+#else
+#define SYS_ARCH_EXT extern
+#endif
+
+/*-----------------macros-----------------------------------------------------*/
+#define LWIP_STK_SIZE 512
+#define LWIP_TASK_MAX 8
+/* The user can change this priority level.
+ * It is important that there was no crossing with other levels.
+ */
+#define LWIP_TSK_PRIO 3
+#define LWIP_TASK_START_PRIO LWIP_TSK_PRIO
+#define LWIP_TASK_END_PRIO LWIP_TSK_PRIO +LWIP_TASK_MAX
+
+/* This is the number of threads that can be started with sys_thread_new() */
+#define SYS_THREAD_MAX 6
+
+#define MAX_QUEUES 10 // ��Ϣ���������
+#define MAX_QUEUE_ENTRIES 20 // ÿ����Ϣ����Ĵ�С
+
+#define SYS_MBOX_NULL (void *)0
+#define SYS_SEM_NULL (void *)0
+
+//#define sys_arch_mbox_tryfetch(mbox,msg) sys_arch_mbox_fetch(mbox,msg,1)
+/** struct of LwIP mailbox */
+
+
+// typedef OS_SEM sys_sem_t; // type of semiphores
+// typedef OS_MUTEX sys_mutex_t; // type of mutex
+// typedef OS_Q sys_mbox_t; // type of mailboxes
+// typedef CPU_INT08U sys_thread_t; // type of id of the new thread
+// typedef CPU_INT08U sys_prot_t;
+typedef void* sys_sem_t;
+typedef void* sys_mutex_t;
+typedef void* sys_mbox_t;
+typedef void* sys_thread_t;
+typedef unsigned long sys_prot_t;
+
+#define portMAX_DELAY 0xffffffffUL
+
+#endif /* __SYS_RTXC_H__ */
+
--- /dev/null
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt
+ *
+ */
+#ifndef LWIP_HDR_LWIPOPTS_H__
+#define LWIP_HDR_LWIPOPTS_H__
+
+/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */
+#if 0
+#define NO_SYS 1
+#else
+#define NO_SYS 0
+#define LWIP_COMPAT_MUTEX_ALLOWED 1
+#endif
+
+#define LWIP_NETCONN 0
+#define LWIP_SOCKET 0
+#define SYS_LIGHTWEIGHT_PROT 0
+#define LWIP_COMPAT_MUTEX 2
+#define LWIP_IPV6 1
+#define IPV6_FRAG_COPYHEADER 1
+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0
+
+/* Enable some protocols to test them */
+#define LWIP_DHCP 0
+#define LWIP_AUTOIP 0
+
+#define LWIP_IGMP 1
+#define LWIP_DNS 1
+
+#define LWIP_ALTCP 1
+
+/* Turn off checksum verification of fuzzed data */
+#define CHECKSUM_CHECK_IP 0
+#define CHECKSUM_CHECK_UDP 0
+#define CHECKSUM_CHECK_TCP 0
+#define CHECKSUM_CHECK_ICMP 0
+#define CHECKSUM_CHECK_ICMP6 0
+
+/* Minimal changes to opt.h required for tcp unit tests: */
+#define MEM_SIZE 16000
+#define TCP_SND_QUEUELEN 40
+#define MEMP_NUM_TCP_SEG TCP_SND_QUEUELEN
+#define TCP_OVERSIZE 1
+#define TCP_SND_BUF (12 * TCP_MSS)
+#define TCP_WND (10 * TCP_MSS)
+#define LWIP_WND_SCALE 1
+#define TCP_RCV_SCALE 2
+#define PBUF_POOL_SIZE 400 /* pbuf tests need ~200KByte */
+
+/* Minimal changes to opt.h required for etharp unit tests: */
+#define ETHARP_SUPPORT_STATIC_ENTRIES 1
+
+#define LWIP_NUM_NETIF_CLIENT_DATA 1
+#define LWIP_SNMP 1
+#define MIB2_STATS 1
+#define LWIP_MDNS_RESPONDER 1
+
+#endif /* LWIP_HDR_LWIPOPTS_H__ */
configure_file(${LWIP_DIR}/src/include/lwip/init.h.cmake.in ${LWIP_DIR}/src/include/lwip/init.h)
# Documentation
-set(DOXYGEN_DIR ${LWIP_DIR}/doc/doxygen)
-set(DOXYGEN_OUTPUT_DIR output)
-set(DOXYGEN_IN ${LWIP_DIR}/doc/doxygen/lwip.Doxyfile.cmake.in)
-set(DOXYGEN_OUT ${LWIP_DIR}/doc/doxygen/lwip.Doxyfile)
-configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT})
+# set(DOXYGEN_DIR ${LWIP_DIR}/doc/doxygen)
+# set(DOXYGEN_OUTPUT_DIR output)
+# set(DOXYGEN_IN ${LWIP_DIR}/doc/doxygen/lwip.Doxyfile.cmake.in)
+# set(DOXYGEN_OUT ${LWIP_DIR}/doc/doxygen/lwip.Doxyfile)
+# configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT})
-find_package(Doxygen)
-if (DOXYGEN_FOUND)
- message("Doxygen build started")
-
- add_custom_target(lwipdocs
- COMMAND ${CMAKE_COMMAND} -E remove_directory ${DOXYGEN_DIR}/${DOXYGEN_OUTPUT_DIR}/html
- COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
- WORKING_DIRECTORY ${DOXYGEN_DIR}
- COMMENT "Generating API documentation with Doxygen"
- VERBATIM)
-else (DOXYGEN_FOUND)
- message("Doxygen needs to be installed to generate the doxygen documentation")
-endif (DOXYGEN_FOUND)
+# find_package(Doxygen)
+# if (DOXYGEN_FOUND)
+ # message("Doxygen build started")
+#
+ # add_custom_target(lwipdocs
+ # COMMAND ${CMAKE_COMMAND} -E remove_directory ${DOXYGEN_DIR}/${DOXYGEN_OUTPUT_DIR}/html
+ # COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
+ # WORKING_DIRECTORY ${DOXYGEN_DIR}
+ # COMMENT "Generating API documentation with Doxygen"
+ # VERBATIM)
+# else (DOXYGEN_FOUND)
+ # message("Doxygen needs to be installed to generate the doxygen documentation")
+# endif (DOXYGEN_FOUND)
# lwIP libraries
-add_library(lwipcore EXCLUDE_FROM_ALL ${lwipnoapps_SRCS})
-target_compile_options(lwipcore PRIVATE ${LWIP_COMPILER_FLAGS})
-target_compile_definitions(lwipcore PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
-target_include_directories(lwipcore PRIVATE ${LWIP_INCLUDE_DIRS} ${LWIP_MBEDTLS_INCLUDE_DIRS})
+# add_library(lwipcore EXCLUDE_FROM_ALL ${lwipnoapps_SRCS})
+# target_compile_options(lwipcore PRIVATE ${LWIP_COMPILER_FLAGS})
+# target_compile_definitions(lwipcore PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
+# target_include_directories(lwipcore PRIVATE ${LWIP_INCLUDE_DIRS} ${LWIP_MBEDTLS_INCLUDE_DIRS})
-add_library(lwipallapps EXCLUDE_FROM_ALL ${lwipallapps_SRCS})
-target_compile_options(lwipallapps PRIVATE ${LWIP_COMPILER_FLAGS})
-target_compile_definitions(lwipallapps PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
-target_include_directories(lwipallapps PRIVATE ${LWIP_INCLUDE_DIRS} ${LWIP_MBEDTLS_INCLUDE_DIRS})
+# add_library(lwipallapps EXCLUDE_FROM_ALL ${lwipallapps_SRCS})
+# target_compile_options(lwipallapps PRIVATE ${LWIP_COMPILER_FLAGS})
+# target_compile_definitions(lwipallapps PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
+# target_include_directories(lwipallapps PRIVATE ${LWIP_INCLUDE_DIRS} ${LWIP_MBEDTLS_INCLUDE_DIRS})
* (unless it has been created by accept()). */
sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1);
sockets[i].errevent = 0;
- init_waitqueue_head(&sockets[i].wq);
+ // init_waitqueue_head(&sockets[i].wq);
#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */
return i + LWIP_SOCKET_OFFSET;
}
#if !defined(LWIP_HAVE_INT64) && defined(UINT64_MAX)
#define LWIP_HAVE_INT64 1
#endif
-typedef uint8_t u8_t;
-typedef int8_t s8_t;
-typedef uint16_t u16_t;
-typedef int16_t s16_t;
-typedef uint32_t u32_t;
-typedef int32_t s32_t;
+// typedef uint8_t u8_t;
+// typedef int8_t s8_t;
+// typedef uint16_t u16_t;
+// typedef int16_t s16_t;
+// typedef uint32_t u32_t;
+// typedef int32_t s32_t;
#if LWIP_HAVE_INT64
typedef uint64_t u64_t;
typedef int64_t s64_t;
#endif
-typedef uintptr_t mem_ptr_t;
+// typedef uintptr_t mem_ptr_t;
#endif
/** Define this to 1 in arch/cc.h of your port if your compiler does not provide