feat(factory): add GNSS test and LED status modes
This commit is contained in:
@@ -9,12 +9,14 @@
|
||||
#include "ql_iic.h"
|
||||
#include "ql_nw.h"
|
||||
#include "ql_power.h"
|
||||
#include "ql_pwm.h"
|
||||
#include "ql_rtos.h"
|
||||
#include "ql_sim.h"
|
||||
#include "sockets.h"
|
||||
|
||||
#include "DP1312EA.h"
|
||||
#include "factory_audio.h"
|
||||
#include "factory_gnss.h"
|
||||
#include "factory_protocol.h"
|
||||
#include "factory_test.h"
|
||||
#include "nfc.h"
|
||||
@@ -34,24 +36,96 @@ static char g_ip_address[64];
|
||||
static volatile int g_led_mode;
|
||||
static ql_task_t g_led_task;
|
||||
|
||||
enum {
|
||||
FT_LED_OFF = 0,
|
||||
FT_LED_ON,
|
||||
FT_LED_LOOPBACK,
|
||||
FT_LED_NFC,
|
||||
FT_LED_GNSS
|
||||
};
|
||||
|
||||
static int factory_led_pwm_set(unsigned short duty, int *enabled)
|
||||
{
|
||||
QL_PWM_CONFIG_EX config;
|
||||
|
||||
config.pwm_psc = 1;
|
||||
config.high_one_cycle_duration = duty;
|
||||
config.total_one_cycle_duration = 320;
|
||||
config.clk_src = QL_PWM_CLK_SRC_32K;
|
||||
if (ql_pwm_config_plus_ex(FT_STATUS_LED_PIN, &config) != 0) return -1;
|
||||
if (!*enabled) {
|
||||
if (ql_pwm_enable(FT_STATUS_LED_PIN) != 0) {
|
||||
ql_pwm_disable(FT_STATUS_LED_PIN);
|
||||
return -1;
|
||||
}
|
||||
*enabled = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void factory_led_pwm_stop(int *enabled)
|
||||
{
|
||||
if (*enabled) ql_pwm_disable(FT_STATUS_LED_PIN);
|
||||
*enabled = 0;
|
||||
}
|
||||
|
||||
static void factory_led_task(void *arg)
|
||||
{
|
||||
int phase = 0;
|
||||
int last_mode = -1;
|
||||
int pwm_enabled = 0;
|
||||
int pwm_failed = 0;
|
||||
int breath_duty = 16;
|
||||
int breath_step = 16;
|
||||
(void)arg;
|
||||
ql_gpio_init(FT_STATUS_LED_PIN, PIN_DIRECTION_OUT, PIN_PULL_DISABLE,
|
||||
PIN_LEVEL_HIGH);
|
||||
while (1) {
|
||||
if (g_led_mode == 0) {
|
||||
int mode = g_led_mode;
|
||||
if (mode != last_mode) {
|
||||
phase = 0;
|
||||
breath_duty = 16;
|
||||
breath_step = 16;
|
||||
pwm_failed = 0;
|
||||
last_mode = mode;
|
||||
}
|
||||
if (mode == FT_LED_GNSS && !pwm_failed) {
|
||||
if (factory_led_pwm_set((unsigned short)breath_duty,
|
||||
&pwm_enabled) == 0) {
|
||||
breath_duty += breath_step;
|
||||
if (breath_duty >= 304 || breath_duty <= 16) {
|
||||
breath_step = -breath_step;
|
||||
}
|
||||
ql_rtos_task_sleep_ms(40);
|
||||
continue;
|
||||
}
|
||||
pwm_failed = 1;
|
||||
factory_led_pwm_stop(&pwm_enabled);
|
||||
printf("[FT_LED] GPIO70 PWM unavailable, use GNSS double-flash\r\n");
|
||||
}
|
||||
if (pwm_enabled) {
|
||||
factory_led_pwm_stop(&pwm_enabled);
|
||||
ql_gpio_init(FT_STATUS_LED_PIN, PIN_DIRECTION_OUT,
|
||||
PIN_PULL_DISABLE, PIN_LEVEL_HIGH);
|
||||
}
|
||||
if (mode == FT_LED_OFF) {
|
||||
ql_gpio_set_level(FT_STATUS_LED_PIN, PIN_LEVEL_LOW);
|
||||
ql_rtos_task_sleep_ms(100);
|
||||
} else if (g_led_mode == 1) {
|
||||
} else if (mode == FT_LED_ON) {
|
||||
ql_gpio_set_level(FT_STATUS_LED_PIN, PIN_LEVEL_HIGH);
|
||||
ql_rtos_task_sleep_ms(100);
|
||||
} else if (mode == FT_LED_GNSS) {
|
||||
static const int levels[] = {1, 0, 1, 0};
|
||||
static const int delays[] = {80, 80, 80, 520};
|
||||
ql_gpio_set_level(FT_STATUS_LED_PIN,
|
||||
levels[phase] ? PIN_LEVEL_HIGH : PIN_LEVEL_LOW);
|
||||
ql_rtos_task_sleep_ms(delays[phase]);
|
||||
phase = (phase + 1) % 4;
|
||||
} else {
|
||||
phase = !phase;
|
||||
ql_gpio_set_level(FT_STATUS_LED_PIN,
|
||||
phase ? PIN_LEVEL_HIGH : PIN_LEVEL_LOW);
|
||||
ql_rtos_task_sleep_ms(g_led_mode == 2 ? 250 : 100);
|
||||
ql_rtos_task_sleep_ms(mode == FT_LED_LOOPBACK ? 250 : 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,9 +197,9 @@ static ft_error_t run_audio_loopback(char *data, unsigned int data_size)
|
||||
if (ret != 0) {
|
||||
return FT_ERR_AUDIO_PLAY;
|
||||
}
|
||||
factory_led_mode(2);
|
||||
factory_led_mode(FT_LED_LOOPBACK);
|
||||
ret = factory_audio_wait_and_loopback(FT_DIALOG_KEY_TIMEOUT_MS, &recorded_ms);
|
||||
factory_led_mode(1);
|
||||
factory_led_mode(FT_LED_ON);
|
||||
snprintf(data, data_size,
|
||||
"{\"recorded_ms\":%lu,\"max_ms\":%d,\"volume_percent\":100}",
|
||||
(unsigned long)recorded_ms, FT_AUDIO_MAX_MS);
|
||||
@@ -211,12 +285,12 @@ static ft_error_t run_nfc(char *data, unsigned int data_size)
|
||||
if (audio_ret != 0) {
|
||||
return FT_ERR_AUDIO_PLAY;
|
||||
}
|
||||
factory_led_mode(3);
|
||||
factory_led_mode(FT_LED_NFC);
|
||||
DP1312EA_Reset();
|
||||
version = DP1312EA_ReadRawRC(VersionReg);
|
||||
if (version != FT_NFC_VERSION_EXPECTED) {
|
||||
snprintf(data, data_size, "{\"chip_version\":\"0x%02X\"}", version);
|
||||
factory_led_mode(1);
|
||||
factory_led_mode(FT_LED_ON);
|
||||
return FT_ERR_NFC_CHIP;
|
||||
}
|
||||
|
||||
@@ -227,16 +301,54 @@ static ft_error_t run_nfc(char *data, unsigned int data_size)
|
||||
snprintf(data, data_size,
|
||||
"{\"chip_version\":\"0x%02X\",\"uid\":\"%s\"}",
|
||||
version, (char *)output_uuid);
|
||||
factory_led_mode(1);
|
||||
factory_led_mode(FT_LED_ON);
|
||||
return FT_OK;
|
||||
}
|
||||
ql_rtos_task_sleep_ms(200);
|
||||
} while (ft_now_ms() - start < FT_NFC_TIMEOUT_MS);
|
||||
|
||||
factory_led_mode(1);
|
||||
factory_led_mode(FT_LED_ON);
|
||||
return FT_ERR_NFC_TIMEOUT;
|
||||
}
|
||||
|
||||
static ft_error_t run_gnss(char *data, unsigned int data_size)
|
||||
{
|
||||
factory_gnss_result_t result;
|
||||
int audio_ret;
|
||||
|
||||
factory_led_mode(FT_LED_GNSS);
|
||||
audio_ret = factory_audio_play_prompt(FT_AUDIO_GNSS_PATH);
|
||||
if (audio_ret != 0) {
|
||||
factory_gnss_stop();
|
||||
factory_led_mode(FT_LED_ON);
|
||||
return audio_ret == -2 ? FT_ERR_AUDIO_FILE_MISSING : FT_ERR_AUDIO_PLAY;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
factory_gnss_snapshot(&result);
|
||||
if (result.open_ret == 0 && result.nmea_count >= 1 &&
|
||||
(result.sat_count >= 1 || result.fix_status > 0)) {
|
||||
snprintf(data, data_size,
|
||||
"{\"open_ret\":%d,\"nmea_count\":%lu,\"sat_count\":%d,"
|
||||
"\"fix_status\":%d,\"search_ms\":%lu,"
|
||||
"\"required_nmea_count\":1,\"required_sat_count\":1}",
|
||||
result.open_ret, (unsigned long)result.nmea_count,
|
||||
result.sat_count, result.fix_status,
|
||||
(unsigned long)result.search_ms);
|
||||
factory_gnss_stop();
|
||||
factory_led_mode(FT_LED_ON);
|
||||
return FT_OK;
|
||||
}
|
||||
|
||||
if (result.open_ret != 0) {
|
||||
ql_rtos_task_sleep_s(2);
|
||||
factory_gnss_start();
|
||||
} else {
|
||||
ql_rtos_task_sleep_ms(500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ft_error_t run_node(ft_node_t node, char *data, unsigned int data_size)
|
||||
{
|
||||
data[0] = '\0';
|
||||
@@ -247,6 +359,7 @@ static ft_error_t run_node(ft_node_t node, char *data, unsigned int data_size)
|
||||
case FT_NODE_ESIM: return run_esim(data, data_size);
|
||||
case FT_NODE_DATA_CALL: return run_data_call(data, data_size);
|
||||
case FT_NODE_NFC: return run_nfc(data, data_size);
|
||||
case FT_NODE_GNSS: return run_gnss(data, data_size);
|
||||
default: return FT_ERR_NFC_LOCKED;
|
||||
}
|
||||
}
|
||||
@@ -261,10 +374,11 @@ static void factory_test_task(void *arg)
|
||||
int audio_ret;
|
||||
(void)arg;
|
||||
|
||||
factory_gnss_start();
|
||||
ql_rtos_task_sleep_s(2);
|
||||
ft_protocol_init();
|
||||
ql_rtos_task_create(&g_led_task, 2048, 15, "ft_led", factory_led_task, NULL);
|
||||
factory_led_mode(1);
|
||||
factory_led_mode(FT_LED_ON);
|
||||
if (ql_dev_get_imei(imei, sizeof(imei)) == 0) {
|
||||
ft_protocol_set_imei(imei);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user