feat(upload): update OOB upload URL format and make CAN speeds INI-configurable
- Change upload URL path: golf.cgi -> golf-golface.cgi
- Add upload_dev INI key (1=dev, appends &dev=1 to URL)
- Change query params: ?filename= -> ?did={device_id}&vid={event_id}
- Add event_recorder_init params: device_id, dev_mode, speed_normal/alert/stop
- Make CAN speed limits configurable via [can] speed_normal/alert/stop in INI
(replaces hardcoded SPEED_LIMIT_* macros with runtime static vars)
- Fix build_targz: use tar -C + mkdir -p for BusyBox compat;
use open()+lseek() instead of stat() (struct stat ABI mismatch on target)
- Extend TEST_UPLOAD snapshot poll timeout: 5s -> 15s; same lseek fix
- Add BLE SET command: persist_ini_int() for runtime INI parameter update
- Fix app_header_init: elapsed_us long -> long long (overflow guard)
- Remove verbose debug printf from mcp2515 reset/send paths
- can_bus: wrap CTL log printf in #if 1 for easy toggle
This commit is contained in:
parent
83e2256192
commit
2081c7b1f5
@ -29,7 +29,10 @@ void event_recorder_init(const char *upload_url,
|
|||||||
int upload_delay_ms,
|
int upload_delay_ms,
|
||||||
int enable,
|
int enable,
|
||||||
const char *device_id,
|
const char *device_id,
|
||||||
int dev_mode);
|
int dev_mode,
|
||||||
|
int speed_normal,
|
||||||
|
int speed_alert,
|
||||||
|
int speed_stop);
|
||||||
|
|
||||||
/* Drive the state machine — call from app_header_recv_inference. */
|
/* Drive the state machine — call from app_header_recv_inference. */
|
||||||
void event_recorder_update(const stdc_analysis_t *ana);
|
void event_recorder_update(const stdc_analysis_t *ana);
|
||||||
|
|||||||
@ -24,7 +24,7 @@ SegOverlayEnable = 0 # 0: outline only, 1: also paint per-class colour ov
|
|||||||
OnlyPerson = 1 # only draw person bounding box when DrawBoxEnable
|
OnlyPerson = 1 # only draw person bounding box when DrawBoxEnable
|
||||||
#(so far for yolo only, JobId = 11)
|
#(so far for yolo only, JobId = 11)
|
||||||
DrawOnResize = 0; # If InferenceStream is 0. This setting needs to be enabled. The box will be drawn on all resize streams.
|
DrawOnResize = 0; # If InferenceStream is 0. This setting needs to be enabled. The box will be drawn on all resize streams.
|
||||||
verbose_log = 0 # 0: quiet (warnings only, ~30B/s), 1: per-frame class ratios every 20 frames (~1KB/s). Toggle from web UI.
|
verbose_log = 1 # 0: quiet (warnings only, ~30B/s), 1: per-frame class ratios every 20 frames (~1KB/s). Toggle from web UI.
|
||||||
|
|
||||||
NnmSource = 0 # 0: run host_stream independently, 1: run with streamer
|
NnmSource = 0 # 0: run host_stream independently, 1: run with streamer
|
||||||
ssm_name = "vsrc_ssm_ifp_0" # If NnmSource is 1. This setting needs to be set. The name is automaticlly create by streamer.
|
ssm_name = "vsrc_ssm_ifp_0" # If NnmSource is 1. This setting needs to be set. The name is automaticlly create by streamer.
|
||||||
@ -112,3 +112,6 @@ enable = 1 # 1: enable CAN bus output; 0: disabled
|
|||||||
spidev = /dev/spidev1.0 # SPI device path for MCP2515
|
spidev = /dev/spidev1.0 # SPI device path for MCP2515
|
||||||
speed_kbps = 250 # CAN bus speed: 125 / 250 / 500 / 1000 kbps
|
speed_kbps = 250 # CAN bus speed: 125 / 250 / 500 / 1000 kbps
|
||||||
can_id = 0x100 # 11-bit standard frame ID for outbound event frames
|
can_id = 0x100 # 11-bit standard frame ID for outbound event frames
|
||||||
|
speed_normal = 240 # CAN speed command: normal driving
|
||||||
|
speed_alert = 35 # CAN speed command: slow/alert (person or obstacle detected)
|
||||||
|
speed_stop = 10 # CAN speed command: stop/emergency
|
||||||
|
|||||||
@ -525,9 +525,9 @@ int app_header_recv_inference(uint32_t buf_addr, bool *bl_run_next_inference)
|
|||||||
static struct timeval s_last_log = {0, 0};
|
static struct timeval s_last_log = {0, 0};
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, NULL);
|
||||||
long elapsed_us = (now.tv_sec - s_last_log.tv_sec) * 1000000L
|
long long elapsed_us = (long long)(now.tv_sec - s_last_log.tv_sec) * 1000000LL
|
||||||
+ (now.tv_usec - s_last_log.tv_usec);
|
+ (long long)(now.tv_usec - s_last_log.tv_usec);
|
||||||
if (elapsed_us >= 1000000L) {
|
if (elapsed_us >= 1000000LL) {
|
||||||
s_last_log = now;
|
s_last_log = now;
|
||||||
log_trim_if_needed(); /* keep /tmp/fw.log under LOG_MAX_BYTES */
|
log_trim_if_needed(); /* keep /tmp/fw.log under LOG_MAX_BYTES */
|
||||||
if (g_verbose_log) {
|
if (g_verbose_log) {
|
||||||
|
|||||||
@ -671,12 +671,13 @@ void can_bus_send_control_cmd(const can_ctrl_cmd_t *ctrl)
|
|||||||
frame[6] = (ctrl->led_enable & 1);
|
frame[6] = (ctrl->led_enable & 1);
|
||||||
frame[7] = (ctrl->led_r & 1) | ((ctrl->led_l & 1) << 7);
|
frame[7] = (ctrl->led_r & 1) | ((ctrl->led_l & 1) << 7);
|
||||||
rc = send_one_frame_with_retry(s_ctl_can_id, frame, 8);
|
rc = send_one_frame_with_retry(s_ctl_can_id, frame, 8);
|
||||||
|
#if 1
|
||||||
if (rc == ERROR_OK) {
|
if (rc == ERROR_OK) {
|
||||||
printf("[CAN-CTL] tx id=0x%03X dlc=8 data=[0x%02X 0x%02X 00 00 00 00 0x%02X 0x%02X]\n",
|
printf("[CAN-CTL] tx id=0x%03X dlc=8 data=[0x%02X 0x%02X 00 00 00 00 0x%02X 0x%02X]\n",s_ctl_can_id, frame[0], frame[1], frame[6], frame[7]);
|
||||||
s_ctl_can_id, frame[0], frame[1], frame[6], frame[7]);
|
|
||||||
} else {
|
} else {
|
||||||
printf("[CAN-CTL] tx failed (speed=%u rc=%d)\n", ctrl->speed, rc);
|
printf("[CAN-CTL] tx failed (speed=%u rc=%d)\n", ctrl->speed, rc);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void can_bus_close(void)
|
void can_bus_close(void)
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -48,6 +49,10 @@
|
|||||||
/* ── External (from kdp2_host_stream.c) ──────────────────────────────────── */
|
/* ── External (from kdp2_host_stream.c) ──────────────────────────────────── */
|
||||||
extern VMF_VSRC_HANDLE_T *g_ptVsrcHandle;
|
extern VMF_VSRC_HANDLE_T *g_ptVsrcHandle;
|
||||||
|
|
||||||
|
/* ── External globals settable via BLE SET command ───────────────────────── */
|
||||||
|
extern unsigned int g_dwSegOverlayEnable; /* defined in kp_firmware.c */
|
||||||
|
extern unsigned int g_verbose_log; /* defined in kp_firmware.c */
|
||||||
|
|
||||||
/* ── Speed control via MsgBroker ─────────────────────────────────────────── */
|
/* ── Speed control via MsgBroker ─────────────────────────────────────────── */
|
||||||
/* Must be defined before any caller (grass state machine, single-shot). */
|
/* Must be defined before any caller (grass state machine, single-shot). */
|
||||||
static int msg_send(const char *fifo,
|
static int msg_send(const char *fifo,
|
||||||
@ -112,15 +117,16 @@ static int s_up_port = 80;
|
|||||||
static char s_up_path[128] = "/api/golf-golface.cgi";
|
static char s_up_path[128] = "/api/golf-golface.cgi";
|
||||||
static char s_device_id[64] = "";
|
static char s_device_id[64] = "";
|
||||||
static int s_upload_dev = 0;
|
static int s_upload_dev = 0;
|
||||||
|
static char s_ini_path[256] = "./ini/host_stream.ini"; /* for SET → sed persistence */
|
||||||
|
|
||||||
static char s_sd_path[256] = "/tmp/sdcard/events";
|
static char s_sd_path[256] = "/tmp/sdcard/events";
|
||||||
static long long s_sd_max_bytes = (long long)7 * 1024 * 1024 * 1024;
|
static long long s_sd_max_bytes = (long long)7 * 1024 * 1024 * 1024;
|
||||||
static int s_upload_delay_ms = 60000;
|
static int s_upload_delay_ms = 60000;
|
||||||
static int s_enabled = 0;
|
static int s_enabled = 0;
|
||||||
|
|
||||||
#define SPEED_LIMIT_NORMAL 240//255 /* <20><><EFBFBD>`<60><>p */
|
static uint8_t s_speed_normal = 240; /* normal driving — configurable via [can] speed_normal */
|
||||||
#define SPEED_LIMIT_ALERT 35 /* <20><>a/ĵ<><C4B5> (<28><><EFBFBD><EFBFBD><EFBFBD>a level <20>Τ@) */
|
static uint8_t s_speed_alert = 35; /* slow/alert — configurable via [can] speed_alert */
|
||||||
#define SPEED_LIMIT_STOP 10 /* <20>I<EFBFBD><49>/<2F><><EFBFBD> */
|
static uint8_t s_speed_stop = 10; /* stop/emergency — configurable via [can] speed_stop */
|
||||||
|
|
||||||
/* Speed levels sent via MsgBroker → CAN bus process.
|
/* Speed levels sent via MsgBroker → CAN bus process.
|
||||||
* To tune: adjust the numbers here only — no logic changes needed.
|
* To tune: adjust the numbers here only — no logic changes needed.
|
||||||
@ -361,23 +367,36 @@ static void build_targz(const char *work_dir, const char *event_id,
|
|||||||
strftime(ts, sizeof(ts), "%Y%m%d_%H%M%S", t);
|
strftime(ts, sizeof(ts), "%Y%m%d_%H%M%S", t);
|
||||||
|
|
||||||
snprintf(out_path, out_n, "%s/event_%s_%s.tar.gz", s_sd_path, event_id, ts);
|
snprintf(out_path, out_n, "%s/event_%s_%s.tar.gz", s_sd_path, event_id, ts);
|
||||||
mkdir(s_sd_path, 0755);
|
|
||||||
|
|
||||||
char cmd[768];
|
char cmd[768];
|
||||||
|
/* BusyBox v1.27.2 tar does NOT support -z flag (no gzip built-in).
|
||||||
|
* Use explicit pipe to /bin/gzip instead.
|
||||||
|
* mkdir -p creates the sd_path in case it does not yet exist. */
|
||||||
snprintf(cmd, sizeof(cmd),
|
snprintf(cmd, sizeof(cmd),
|
||||||
"(cd '%s' && tar cf - . 2>>/tmp/fw.log) | gzip -c > '%s'",
|
"mkdir -p '%s' && tar cf - -C '%s' . 2>>/tmp/fw.log | /bin/gzip -c > '%s'",
|
||||||
work_dir, out_path);
|
s_sd_path, work_dir, out_path);
|
||||||
|
printf("[EVT] build_targz: work_dir=%s sd=%s\n", work_dir, s_sd_path);
|
||||||
|
printf("[EVT] build_targz: cmd=%s\n", cmd);
|
||||||
|
fflush(stdout);
|
||||||
int sys_rc = system(cmd);
|
int sys_rc = system(cmd);
|
||||||
|
|
||||||
sync();
|
sync();
|
||||||
|
|
||||||
struct stat _st;
|
/* stat() st_size is unreliable on this target (struct stat ABI mismatch).
|
||||||
if (stat(out_path, &_st) != 0) {
|
* Use open()+lseek(SEEK_END) to obtain the true file size. */
|
||||||
printf("[EVT] tar/gzip failed (shell rc=%d) — file not created\n", sys_rc);
|
{
|
||||||
|
int _fd = open(out_path, O_RDONLY);
|
||||||
|
long _sz = (_fd >= 0) ? (long)lseek(_fd, 0, SEEK_END) : -1L;
|
||||||
|
if (_fd >= 0) close(_fd);
|
||||||
|
if (_sz <= 0) {
|
||||||
|
printf("[EVT] tar/gzip: empty/missing output (shell rc=%d lseek=%ld) — treating as failed\n",
|
||||||
|
sys_rc, _sz);
|
||||||
|
fflush(stdout);
|
||||||
out_path[0] = '\0';
|
out_path[0] = '\0';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
printf("[EVT] created %s (%ld bytes)\n", out_path, (long)_st.st_size);
|
printf("[EVT] created %s (%ld bytes)\n", out_path, _sz);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct { char path[320]; time_t mtime; } FileEntry;
|
typedef struct { char path[320]; time_t mtime; } FileEntry;
|
||||||
@ -470,7 +489,7 @@ static void test_mode_exit_internal(const char *reason)
|
|||||||
{
|
{
|
||||||
g_test_mode = 0;
|
g_test_mode = 0;
|
||||||
s_test_mode_entered = 0;
|
s_test_mode_entered = 0;
|
||||||
can_ctrl_cmd_t ctrl = { .speed = SPEED_LIMIT_NORMAL,
|
can_ctrl_cmd_t ctrl = { .speed = s_speed_normal,
|
||||||
.led_enable = 0, .led_r = 0, .led_l = 0,
|
.led_enable = 0, .led_r = 0, .led_l = 0,
|
||||||
.keepalive_interval_ms = 0 };
|
.keepalive_interval_ms = 0 };
|
||||||
can_bus_send_control_cmd(&ctrl);
|
can_bus_send_control_cmd(&ctrl);
|
||||||
@ -567,12 +586,12 @@ static void *test_can_all_thread(void *arg)
|
|||||||
{
|
{
|
||||||
int obs = arg ? (int)(intptr_t)arg : TEST_OBS_DEFAULT_SEC;
|
int obs = arg ? (int)(intptr_t)arg : TEST_OBS_DEFAULT_SEC;
|
||||||
test_reply("TEST_CAN_ALL_START");
|
test_reply("TEST_CAN_ALL_START");
|
||||||
test_can_event("VIOLATION", 1, SPEED_LIMIT_ALERT); sleep(obs);
|
test_can_event("VIOLATION", 1, s_speed_alert); sleep(obs);
|
||||||
test_can_event("VIOLATION", 0, SPEED_LIMIT_NORMAL); sleep(3);
|
test_can_event("VIOLATION", 0, s_speed_normal); sleep(3);
|
||||||
test_can_event("COLLISION", 1, SPEED_LIMIT_STOP); sleep(obs);
|
test_can_event("COLLISION", 1, s_speed_stop); sleep(obs);
|
||||||
test_can_event("COLLISION", 0, SPEED_LIMIT_NORMAL); sleep(3);
|
test_can_event("COLLISION", 0, s_speed_normal); sleep(3);
|
||||||
test_can_event("ALERT", 1, SPEED_LIMIT_ALERT); sleep(obs);
|
test_can_event("ALERT", 1, s_speed_alert); sleep(obs);
|
||||||
test_can_event("ALERT", 0, SPEED_LIMIT_NORMAL); sleep(3);
|
test_can_event("ALERT", 0, s_speed_normal); sleep(3);
|
||||||
test_reply("TEST_CAN_ALL_DONE");
|
test_reply("TEST_CAN_ALL_DONE");
|
||||||
test_mode_exit_internal("CAN_ALL complete");
|
test_mode_exit_internal("CAN_ALL complete");
|
||||||
s_test_all_running = 0;
|
s_test_all_running = 0;
|
||||||
@ -627,22 +646,36 @@ static void *test_upload_thread(void *arg)
|
|||||||
/* Request one JPEG snapshot from the VMF thread */
|
/* Request one JPEG snapshot from the VMF thread */
|
||||||
request_snap(snap_name, work_dir, event_id, evt_type, 1, 0);
|
request_snap(snap_name, work_dir, event_id, evt_type, 1, 0);
|
||||||
|
|
||||||
/* Poll up to 5 s (50 × 100 ms) — stop as soon as file arrives */
|
/* Poll up to 15 s (150 × 100 ms) — stop as soon as file arrives.
|
||||||
|
* Inference submit happens every ~30 frames at ~7 fps (~4.3 s),
|
||||||
|
* plus JPEGEnc init time; 15 s gives ample margin. */
|
||||||
char snap_path[320];
|
char snap_path[320];
|
||||||
snprintf(snap_path, sizeof(snap_path), "%s/%s", work_dir, snap_name);
|
snprintf(snap_path, sizeof(snap_path), "%s/%s", work_dir, snap_name);
|
||||||
struct stat _st;
|
/* stat() st_size is unreliable (struct stat ABI mismatch): use lseek instead. */
|
||||||
int has_snap = 0;
|
int has_snap = 0;
|
||||||
for (int _i = 0; _i < 50; _i++) {
|
for (int _i = 0; _i < 150; _i++) {
|
||||||
usleep(100000); /* 100 ms */
|
usleep(100000); /* 100 ms */
|
||||||
if (stat(snap_path, &_st) == 0 && _st.st_size > 0) {
|
int _pfd = open(snap_path, O_RDONLY);
|
||||||
|
if (_pfd >= 0) {
|
||||||
|
long _psz = (long)lseek(_pfd, 0, SEEK_END);
|
||||||
|
close(_pfd);
|
||||||
|
if (_psz > 0) {
|
||||||
has_snap = 1;
|
has_snap = 1;
|
||||||
printf("[TEST] upload: snapshot %s OK (%ld bytes, waited %d00ms)\n",
|
printf("[TEST] upload: snapshot %s OK (%ld bytes, waited %d00ms)\n",
|
||||||
snap_path, (long)_st.st_size, _i + 1);
|
snap_path, _psz, _i + 1);
|
||||||
|
fflush(stdout);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!has_snap)
|
}
|
||||||
printf("[TEST] upload: snapshot %s missing after 5s\n", snap_path);
|
if (!has_snap) {
|
||||||
|
int _pfd2 = open(snap_path, O_RDONLY);
|
||||||
|
long _psz2 = (_pfd2 >= 0) ? (long)lseek(_pfd2, 0, SEEK_END) : -1L;
|
||||||
|
if (_pfd2 >= 0) close(_pfd2);
|
||||||
|
printf("[TEST] upload: snapshot %s missing after 15s (lseek=%ld)\n",
|
||||||
|
snap_path, _psz2);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
/* Write event.json */
|
/* Write event.json */
|
||||||
char imgs[4][64];
|
char imgs[4][64];
|
||||||
@ -698,12 +731,12 @@ static void *test_all_thread(void *arg)
|
|||||||
|
|
||||||
/* Group 2: CAN only */
|
/* Group 2: CAN only */
|
||||||
test_reply("TEST_ALL_CAN_GROUP_START");
|
test_reply("TEST_ALL_CAN_GROUP_START");
|
||||||
test_can_event("VIOLATION", 1, SPEED_LIMIT_ALERT); sleep(obs);
|
test_can_event("VIOLATION", 1, s_speed_alert); sleep(obs);
|
||||||
test_can_event("VIOLATION", 0, SPEED_LIMIT_NORMAL); sleep(3);
|
test_can_event("VIOLATION", 0, s_speed_normal); sleep(3);
|
||||||
test_can_event("COLLISION", 1, SPEED_LIMIT_STOP); sleep(obs);
|
test_can_event("COLLISION", 1, s_speed_stop); sleep(obs);
|
||||||
test_can_event("COLLISION", 0, SPEED_LIMIT_NORMAL); sleep(3);
|
test_can_event("COLLISION", 0, s_speed_normal); sleep(3);
|
||||||
test_can_event("ALERT", 1, SPEED_LIMIT_ALERT); sleep(obs);
|
test_can_event("ALERT", 1, s_speed_alert); sleep(obs);
|
||||||
test_can_event("ALERT", 0, SPEED_LIMIT_NORMAL); sleep(3);
|
test_can_event("ALERT", 0, s_speed_normal); sleep(3);
|
||||||
test_reply("TEST_ALL_CAN_GROUP_DONE");
|
test_reply("TEST_ALL_CAN_GROUP_DONE");
|
||||||
sleep(3);
|
sleep(3);
|
||||||
|
|
||||||
@ -721,6 +754,165 @@ static void *test_all_thread(void *arg)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── BLE SET command: runtime INI parameter update ───────────────────────── */
|
||||||
|
/* Persist an integer value to the INI file using line-by-line temp-file I/O.
|
||||||
|
* Avoids system()/fork() (SIGCHLD hang) and large stack buffers. */
|
||||||
|
static void persist_ini_int(const char *ini_key, int val)
|
||||||
|
{
|
||||||
|
printf("[SET] persist_ini_int: key=%s val=%d path=%s\n", ini_key, val, s_ini_path);
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
/* Write new content to a temp file alongside the INI */
|
||||||
|
char tmp_path[300];
|
||||||
|
snprintf(tmp_path, sizeof(tmp_path), "%s.tmp", s_ini_path);
|
||||||
|
|
||||||
|
FILE *fin = fopen(s_ini_path, "r");
|
||||||
|
if (!fin) {
|
||||||
|
printf("[SET] WARNING: cannot open %s\n", s_ini_path);
|
||||||
|
fflush(stdout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FILE *fout = fopen(tmp_path, "w");
|
||||||
|
if (!fout) {
|
||||||
|
fclose(fin);
|
||||||
|
printf("[SET] WARNING: cannot create %s\n", tmp_path);
|
||||||
|
fflush(stdout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int key_len = (int)strlen(ini_key);
|
||||||
|
char line[512];
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
while (fgets(line, sizeof(line), fin)) {
|
||||||
|
if (!found && strncmp(line, ini_key, (size_t)key_len) == 0) {
|
||||||
|
const char *p = line + key_len;
|
||||||
|
while (*p == ' ' || *p == '\t') p++;
|
||||||
|
if (*p == '=') {
|
||||||
|
fprintf(fout, "%s = %d\n", ini_key, val);
|
||||||
|
found = 1;
|
||||||
|
continue; /* skip original line */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fputs(line, fout);
|
||||||
|
}
|
||||||
|
fclose(fin);
|
||||||
|
fclose(fout);
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
printf("[SET] WARNING: key=%s not found in %s\n", ini_key, s_ini_path);
|
||||||
|
fflush(stdout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rename(tmp_path, s_ini_path) != 0) {
|
||||||
|
printf("[SET] WARNING: rename failed for %s\n", tmp_path);
|
||||||
|
fflush(stdout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("[SET] persisted: %s = %d\n", ini_key, val);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle "SET key=value" command — works outside test mode.
|
||||||
|
* cmd must already be uppercased (as provided by handle_test_cmd).
|
||||||
|
* Supported keys (case-insensitive from sender):
|
||||||
|
* SegOverlayEnable — 0/1
|
||||||
|
* speed_normal — 1–255
|
||||||
|
* speed_alert — 1–255
|
||||||
|
* speed_stop — 1–255
|
||||||
|
* verbose_log — 0/1
|
||||||
|
*/
|
||||||
|
static void handle_set_cmd(const char *cmd)
|
||||||
|
{
|
||||||
|
/* cmd is already uppercased; format: "SET KEY=VALUE" */
|
||||||
|
const char *p = cmd + 4; /* skip "SET " */
|
||||||
|
while (*p == ' ') p++;
|
||||||
|
|
||||||
|
char key[64] = "", valstr[32] = "";
|
||||||
|
printf("[SET] parsing: [%s]\n", p);
|
||||||
|
fflush(stdout);
|
||||||
|
/* Manual parse: "KEY VALUE" (space-separated) */
|
||||||
|
const char *sp = strchr(p, ' ');
|
||||||
|
if (!sp || sp == p) {
|
||||||
|
bt_uart_send_json("SET_NACK BAD_FORMAT");
|
||||||
|
printf("[SET] bad format (no space): [%s]\n", cmd);
|
||||||
|
fflush(stdout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t klen = (size_t)(sp - p);
|
||||||
|
if (klen >= sizeof(key)) klen = sizeof(key) - 1;
|
||||||
|
memcpy(key, p, klen);
|
||||||
|
key[klen] = '\0';
|
||||||
|
while (*sp == ' ') sp++; /* skip extra spaces */
|
||||||
|
strncpy(valstr, sp, sizeof(valstr) - 1);
|
||||||
|
valstr[sizeof(valstr) - 1] = '\0';
|
||||||
|
/* trim trailing whitespace/CR/LF from valstr */
|
||||||
|
{
|
||||||
|
char *end = valstr + strlen(valstr);
|
||||||
|
while (end > valstr && (*(end-1) == '\r' || *(end-1) == '\n' || *(end-1) == ' '))
|
||||||
|
*(--end) = '\0';
|
||||||
|
}
|
||||||
|
printf("[SET] key=[%s] val=[%s]\n", key, valstr);
|
||||||
|
fflush(stdout);
|
||||||
|
if (key[0] == '\0' || valstr[0] == '\0') {
|
||||||
|
bt_uart_send_json("SET_NACK BAD_FORMAT");
|
||||||
|
fflush(stdout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int val = atoi(valstr);
|
||||||
|
printf("[SET] dispatch key=[%s] val=%d\n", key, val);
|
||||||
|
fflush(stdout);
|
||||||
|
char ack[96];
|
||||||
|
|
||||||
|
if (strcmp(key, "SEGOVERLAYENABLE") == 0) {
|
||||||
|
int v = val ? 1 : 0;
|
||||||
|
printf("[SET] writing g_dwSegOverlayEnable=%d\n", v);
|
||||||
|
fflush(stdout);
|
||||||
|
g_dwSegOverlayEnable = (unsigned int)v;
|
||||||
|
printf("[SET] g_dwSegOverlayEnable OK\n");
|
||||||
|
fflush(stdout);
|
||||||
|
persist_ini_int("SegOverlayEnable", v);
|
||||||
|
snprintf(ack, sizeof(ack), "SET_ACK SegOverlayEnable=%d", v);
|
||||||
|
|
||||||
|
} else if (strcmp(key, "SPEED_NORMAL") == 0) {
|
||||||
|
if (val < 1 || val > 255) { bt_uart_send_json("SET_NACK SPEED_NORMAL OUT_OF_RANGE"); return; }
|
||||||
|
s_speed_normal = (uint8_t)val;
|
||||||
|
persist_ini_int("speed_normal", val);
|
||||||
|
snprintf(ack, sizeof(ack), "SET_ACK speed_normal=%d", val);
|
||||||
|
|
||||||
|
} else if (strcmp(key, "SPEED_ALERT") == 0) {
|
||||||
|
if (val < 1 || val > 255) { bt_uart_send_json("SET_NACK SPEED_ALERT OUT_OF_RANGE"); return; }
|
||||||
|
s_speed_alert = (uint8_t)val;
|
||||||
|
persist_ini_int("speed_alert", val);
|
||||||
|
snprintf(ack, sizeof(ack), "SET_ACK speed_alert=%d", val);
|
||||||
|
|
||||||
|
} else if (strcmp(key, "SPEED_STOP") == 0) {
|
||||||
|
if (val < 1 || val > 255) { bt_uart_send_json("SET_NACK SPEED_STOP OUT_OF_RANGE"); return; }
|
||||||
|
s_speed_stop = (uint8_t)val;
|
||||||
|
persist_ini_int("speed_stop", val);
|
||||||
|
snprintf(ack, sizeof(ack), "SET_ACK speed_stop=%d", val);
|
||||||
|
|
||||||
|
} else if (strcmp(key, "VERBOSE_LOG") == 0) {
|
||||||
|
int v = val ? 1 : 0;
|
||||||
|
g_verbose_log = (unsigned int)v;
|
||||||
|
persist_ini_int("verbose_log", v);
|
||||||
|
snprintf(ack, sizeof(ack), "SET_ACK verbose_log=%d", v);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
snprintf(ack, sizeof(ack), "SET_NACK UNKNOWN_KEY %.48s", key);
|
||||||
|
bt_uart_send_json(ack);
|
||||||
|
printf("[SET] %s\n", ack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bt_uart_send_json(ack);
|
||||||
|
printf("[SET] %s\n", ack);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_test_cmd(const char *raw)
|
static void handle_test_cmd(const char *raw)
|
||||||
{
|
{
|
||||||
char cmd[128];
|
char cmd[128];
|
||||||
@ -744,6 +936,11 @@ static void handle_test_cmd(const char *raw)
|
|||||||
test_mode_exit_internal("user request");
|
test_mode_exit_internal("user request");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* SET works regardless of test mode — runtime parameter update */
|
||||||
|
if (strncmp(cmd, "SET ", 4) == 0) {
|
||||||
|
handle_set_cmd(cmd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!g_test_mode) { test_reply("TEST_ERR NOT_IN_TEST_MODE"); return; }
|
if (!g_test_mode) { test_reply("TEST_ERR NOT_IN_TEST_MODE"); return; }
|
||||||
|
|
||||||
if (strncmp(cmd, "TEST_BLE_ALL", 12) == 0) {
|
if (strncmp(cmd, "TEST_BLE_ALL", 12) == 0) {
|
||||||
@ -771,13 +968,13 @@ static void handle_test_cmd(const char *raw)
|
|||||||
pthread_t tid; pthread_create(&tid, NULL, test_can_all_thread, (void*)(intptr_t)obs); pthread_detach(tid);
|
pthread_t tid; pthread_create(&tid, NULL, test_can_all_thread, (void*)(intptr_t)obs); pthread_detach(tid);
|
||||||
} else if (strncmp(cmd, "TEST_CAN VIOLATION", 18) == 0) {
|
} else if (strncmp(cmd, "TEST_CAN VIOLATION", 18) == 0) {
|
||||||
int lv = atoi(cmd + 18);
|
int lv = atoi(cmd + 18);
|
||||||
test_can_event("VIOLATION", lv, lv ? SPEED_LIMIT_ALERT : SPEED_LIMIT_NORMAL);
|
test_can_event("VIOLATION", lv, lv ? s_speed_alert : s_speed_normal);
|
||||||
} else if (strncmp(cmd, "TEST_CAN COLLISION", 18) == 0) {
|
} else if (strncmp(cmd, "TEST_CAN COLLISION", 18) == 0) {
|
||||||
int lv = atoi(cmd + 18);
|
int lv = atoi(cmd + 18);
|
||||||
test_can_event("COLLISION", lv, lv ? SPEED_LIMIT_STOP : SPEED_LIMIT_NORMAL);
|
test_can_event("COLLISION", lv, lv ? s_speed_stop : s_speed_normal);
|
||||||
} else if (strncmp(cmd, "TEST_CAN ALERT", 14) == 0) {
|
} else if (strncmp(cmd, "TEST_CAN ALERT", 14) == 0) {
|
||||||
int lv = atoi(cmd + 14);
|
int lv = atoi(cmd + 14);
|
||||||
test_can_event("ALERT", lv, lv ? SPEED_LIMIT_ALERT : SPEED_LIMIT_NORMAL);
|
test_can_event("ALERT", lv, lv ? s_speed_alert : s_speed_normal);
|
||||||
} else if (strncmp(cmd, "TEST_BUZZER_ALL", 15) == 0) {
|
} else if (strncmp(cmd, "TEST_BUZZER_ALL", 15) == 0) {
|
||||||
if (s_test_all_running) { test_reply("TEST_ERR ALL_ALREADY_RUNNING"); return; }
|
if (s_test_all_running) { test_reply("TEST_ERR ALL_ALREADY_RUNNING"); return; }
|
||||||
s_test_all_running = 1;
|
s_test_all_running = 1;
|
||||||
@ -830,7 +1027,7 @@ void fire_collision_warning(int level, const char *type)
|
|||||||
"\"content\":{\"level\":%d,\"type\":%s}}",
|
"\"content\":{\"level\":%d,\"type\":%s}}",
|
||||||
level, type_str);
|
level, type_str);
|
||||||
{
|
{
|
||||||
uint8_t speed = level ? SPEED_LIMIT_STOP : SPEED_LIMIT_NORMAL;
|
uint8_t speed = level ? s_speed_stop : s_speed_normal;
|
||||||
can_ctrl_cmd_t ctrl = { .speed = speed, .led_enable = 0,
|
can_ctrl_cmd_t ctrl = { .speed = speed, .led_enable = 0,
|
||||||
.led_r = 0, .led_l = 0, .keepalive_interval_ms = 0 };
|
.led_r = 0, .led_l = 0, .keepalive_interval_ms = 0 };
|
||||||
can_bus_send_control_cmd(&ctrl);
|
can_bus_send_control_cmd(&ctrl);
|
||||||
@ -862,7 +1059,7 @@ static void fire_alert(int left_level, const char *left_type,
|
|||||||
"\"right\":{\"level\":%d,\"type\":%s}}}",
|
"\"right\":{\"level\":%d,\"type\":%s}}}",
|
||||||
left_level, l_str, right_level, r_str);
|
left_level, l_str, right_level, r_str);
|
||||||
{
|
{
|
||||||
uint8_t speed = (left_level || right_level) ? SPEED_LIMIT_ALERT : SPEED_LIMIT_NORMAL;
|
uint8_t speed = (left_level || right_level) ? s_speed_alert : s_speed_normal;
|
||||||
can_ctrl_cmd_t ctrl = { .speed = speed, .led_enable = 0,
|
can_ctrl_cmd_t ctrl = { .speed = speed, .led_enable = 0,
|
||||||
.led_r = 0, .led_l = 0, .keepalive_interval_ms = 0 };
|
.led_r = 0, .led_l = 0, .keepalive_interval_ms = 0 };
|
||||||
can_bus_send_control_cmd(&ctrl);
|
can_bus_send_control_cmd(&ctrl);
|
||||||
@ -995,9 +1192,17 @@ static void save_jpeg(const char *path, const uint8_t *buf, int size)
|
|||||||
printf("[EVT] save_jpeg: cannot open %s\n", path);
|
printf("[EVT] save_jpeg: cannot open %s\n", path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fwrite(buf, 1, (size_t)size, f);
|
size_t written = fwrite(buf, 1, (size_t)size, f);
|
||||||
fclose(f);
|
int ferr = ferror(f);
|
||||||
printf("[EVT] saved %s (%d bytes)\n", path, size);
|
int fcrc = fclose(f);
|
||||||
|
if (fcrc != 0 || ferr) {
|
||||||
|
printf("[EVT] save_jpeg: write error %s (written=%zu ferr=%d fcrc=%d errno=%d)\n",
|
||||||
|
path, written, ferr, fcrc, errno);
|
||||||
|
fflush(stdout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("[EVT] saved %s (requested=%d written=%zu)\n", path, size, written);
|
||||||
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ═══════════════════════════════════════════════════════════════════════════
|
/* ═══════════════════════════════════════════════════════════════════════════
|
||||||
@ -1046,7 +1251,10 @@ void event_recorder_init(const char *upload_url,
|
|||||||
int upload_delay_ms,
|
int upload_delay_ms,
|
||||||
int enable,
|
int enable,
|
||||||
const char *device_id,
|
const char *device_id,
|
||||||
int dev_mode)
|
int dev_mode,
|
||||||
|
int speed_normal,
|
||||||
|
int speed_alert,
|
||||||
|
int speed_stop)
|
||||||
{
|
{
|
||||||
s_enabled = enable;
|
s_enabled = enable;
|
||||||
s_upload_delay_ms = (upload_delay_ms >= 0) ? upload_delay_ms : 60000;
|
s_upload_delay_ms = (upload_delay_ms >= 0) ? upload_delay_ms : 60000;
|
||||||
@ -1060,11 +1268,16 @@ void event_recorder_init(const char *upload_url,
|
|||||||
if (device_id && *device_id) snprintf(s_device_id, sizeof(s_device_id), "%s", device_id);
|
if (device_id && *device_id) snprintf(s_device_id, sizeof(s_device_id), "%s", device_id);
|
||||||
s_upload_dev = dev_mode;
|
s_upload_dev = dev_mode;
|
||||||
|
|
||||||
printf("[EVT] init: enable=%d ch_a=bt_uart ch_b=%s:%d%s did=%s dev=%d sd=%s max=%dMB delay=%dms\n",
|
if (speed_normal > 0) s_speed_normal = (uint8_t)speed_normal;
|
||||||
|
if (speed_alert > 0) s_speed_alert = (uint8_t)speed_alert;
|
||||||
|
if (speed_stop > 0) s_speed_stop = (uint8_t)speed_stop;
|
||||||
|
|
||||||
|
printf("[EVT] init: enable=%d ch_a=bt_uart ch_b=%s:%d%s did=%s dev=%d sd=%s max=%dMB delay=%dms spd=%d/%d/%d\n",
|
||||||
s_enabled,
|
s_enabled,
|
||||||
s_up_host, s_up_port, s_up_path,
|
s_up_host, s_up_port, s_up_path,
|
||||||
s_device_id, s_upload_dev,
|
s_device_id, s_upload_dev,
|
||||||
s_sd_path, sd_max_mb, s_upload_delay_ms);
|
s_sd_path, sd_max_mb, s_upload_delay_ms,
|
||||||
|
s_speed_normal, s_speed_alert, s_speed_stop);
|
||||||
bt_uart_set_extra_cmd_cb(handle_test_cmd);
|
bt_uart_set_extra_cmd_cb(handle_test_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1103,7 +1316,7 @@ void event_recorder_update(const stdc_analysis_t *ana)
|
|||||||
g_grass.state = GRASS_L1;
|
g_grass.state = GRASS_L1;
|
||||||
pthread_mutex_unlock(&g_grass_mtx);
|
pthread_mutex_unlock(&g_grass_mtx);
|
||||||
grass_enter_level(1);
|
grass_enter_level(1);
|
||||||
speed_val = SPEED_LIMIT_STOP;
|
speed_val = s_speed_stop;
|
||||||
msg_send("/tmp/canbus/c0/command.fifo", "host_stream", "setSpeed",&speed_val, sizeof(speed_val), 0);
|
msg_send("/tmp/canbus/c0/command.fifo", "host_stream", "setSpeed",&speed_val, sizeof(speed_val), 0);
|
||||||
buzzer_set_pattern(BUZZER_PATTERN_GRASS);
|
buzzer_set_pattern(BUZZER_PATTERN_GRASS);
|
||||||
return;
|
return;
|
||||||
@ -1118,13 +1331,13 @@ void event_recorder_update(const stdc_analysis_t *ana)
|
|||||||
g_grass.state = GRASS_L2;
|
g_grass.state = GRASS_L2;
|
||||||
pthread_mutex_unlock(&g_grass_mtx);
|
pthread_mutex_unlock(&g_grass_mtx);
|
||||||
grass_enter_level(2);
|
grass_enter_level(2);
|
||||||
speed_val = SPEED_LIMIT_STOP;
|
speed_val = s_speed_stop;
|
||||||
msg_send("/tmp/canbus/c0/command.fifo", "host_stream", "setSpeed",&speed_val, sizeof(speed_val), 0);
|
msg_send("/tmp/canbus/c0/command.fifo", "host_stream", "setSpeed",&speed_val, sizeof(speed_val), 0);
|
||||||
buzzer_set_pattern(BUZZER_PATTERN_GRASS);
|
buzzer_set_pattern(BUZZER_PATTERN_GRASS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
speed_val = SPEED_LIMIT_NORMAL;
|
speed_val = s_speed_normal;
|
||||||
msg_send("/tmp/canbus/c0/command.fifo", "host_stream", "setSpeed",&speed_val, sizeof(speed_val), 0);
|
msg_send("/tmp/canbus/c0/command.fifo", "host_stream", "setSpeed",&speed_val, sizeof(speed_val), 0);
|
||||||
if (!g_last_collision_warning && !g_last_left_alert && !g_last_right_alert)
|
if (!g_last_collision_warning && !g_last_left_alert && !g_last_right_alert)
|
||||||
buzzer_set_pattern(BUZZER_PATTERN_OFF);
|
buzzer_set_pattern(BUZZER_PATTERN_OFF);
|
||||||
@ -1150,12 +1363,12 @@ void event_recorder_update(const stdc_analysis_t *ana)
|
|||||||
g_grass.state = GRASS_L3;
|
g_grass.state = GRASS_L3;
|
||||||
pthread_mutex_unlock(&g_grass_mtx);
|
pthread_mutex_unlock(&g_grass_mtx);
|
||||||
grass_enter_level(3);
|
grass_enter_level(3);
|
||||||
speed_val = SPEED_LIMIT_STOP;
|
speed_val = s_speed_stop;
|
||||||
msg_send("/tmp/canbus/c0/command.fifo", "host_stream", "setSpeed",&speed_val, sizeof(speed_val), 0);
|
msg_send("/tmp/canbus/c0/command.fifo", "host_stream", "setSpeed",&speed_val, sizeof(speed_val), 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
speed_val = SPEED_LIMIT_NORMAL;
|
speed_val = s_speed_normal;
|
||||||
msg_send("/tmp/canbus/c0/command.fifo", "host_stream", "setSpeed",&speed_val, sizeof(speed_val), 0);
|
msg_send("/tmp/canbus/c0/command.fifo", "host_stream", "setSpeed",&speed_val, sizeof(speed_val), 0);
|
||||||
if (!g_last_collision_warning && !g_last_left_alert && !g_last_right_alert)
|
if (!g_last_collision_warning && !g_last_left_alert && !g_last_right_alert)
|
||||||
buzzer_set_pattern(BUZZER_PATTERN_OFF);
|
buzzer_set_pattern(BUZZER_PATTERN_OFF);
|
||||||
@ -1176,11 +1389,11 @@ void event_recorder_update(const stdc_analysis_t *ana)
|
|||||||
case GRASS_L3:
|
case GRASS_L3:
|
||||||
if (on_grass) {
|
if (on_grass) {
|
||||||
gettimeofday(&g_grass.t_last_active, NULL);
|
gettimeofday(&g_grass.t_last_active, NULL);
|
||||||
speed_val = SPEED_LIMIT_STOP;
|
speed_val = s_speed_stop;
|
||||||
msg_send("/tmp/canbus/c0/command.fifo", "host_stream", "setSpeed",&speed_val, sizeof(speed_val), 0);
|
msg_send("/tmp/canbus/c0/command.fifo", "host_stream", "setSpeed",&speed_val, sizeof(speed_val), 0);
|
||||||
buzzer_set_pattern(BUZZER_PATTERN_GRASS);
|
buzzer_set_pattern(BUZZER_PATTERN_GRASS);
|
||||||
} else {
|
} else {
|
||||||
speed_val = SPEED_LIMIT_NORMAL;
|
speed_val = s_speed_normal;
|
||||||
msg_send("/tmp/canbus/c0/command.fifo", "host_stream", "setSpeed",&speed_val, sizeof(speed_val), 0);
|
msg_send("/tmp/canbus/c0/command.fifo", "host_stream", "setSpeed",&speed_val, sizeof(speed_val), 0);
|
||||||
if (!g_last_collision_warning && !g_last_left_alert && !g_last_right_alert)
|
if (!g_last_collision_warning && !g_last_left_alert && !g_last_right_alert)
|
||||||
buzzer_set_pattern(BUZZER_PATTERN_OFF);
|
buzzer_set_pattern(BUZZER_PATTERN_OFF);
|
||||||
@ -1202,7 +1415,7 @@ void event_recorder_update(const stdc_analysis_t *ana)
|
|||||||
/* Upload thread will reset to IDLE when done.
|
/* Upload thread will reset to IDLE when done.
|
||||||
* Keep sending SPEED_LEVEL_5 every frame until upload finishes
|
* Keep sending SPEED_LEVEL_5 every frame until upload finishes
|
||||||
* (keepalive in can_bus.c also maintains this every 200ms). */
|
* (keepalive in can_bus.c also maintains this every 200ms). */
|
||||||
speed_val = SPEED_LIMIT_NORMAL;
|
speed_val = s_speed_normal;
|
||||||
msg_send("/tmp/canbus/c0/command.fifo", "host_stream", "setSpeed",&speed_val, sizeof(speed_val), 0);
|
msg_send("/tmp/canbus/c0/command.fifo", "host_stream", "setSpeed",&speed_val, sizeof(speed_val), 0);
|
||||||
if (!g_last_collision_warning && !g_last_left_alert && !g_last_right_alert)
|
if (!g_last_collision_warning && !g_last_left_alert && !g_last_right_alert)
|
||||||
buzzer_set_pattern(BUZZER_PATTERN_OFF);
|
buzzer_set_pattern(BUZZER_PATTERN_OFF);
|
||||||
@ -1327,7 +1540,17 @@ void event_recorder_provide_frame(void)
|
|||||||
if (snap_ok) {
|
if (snap_ok) {
|
||||||
char out_path[384];
|
char out_path[384];
|
||||||
snprintf(out_path, sizeof(out_path), "%s/%s", req.work_dir, req.filename);
|
snprintf(out_path, sizeof(out_path), "%s/%s", req.work_dir, req.filename);
|
||||||
|
printf("[EVT] snap: saving %s (%d bytes)\n", out_path, jpeg_size);
|
||||||
|
fflush(stdout);
|
||||||
save_jpeg(out_path, jpeg, jpeg_size);
|
save_jpeg(out_path, jpeg, jpeg_size);
|
||||||
|
/* Immediate verify — use lseek (stat st_size unreliable: ABI mismatch) */
|
||||||
|
{
|
||||||
|
int _vfd = open(out_path, O_RDONLY);
|
||||||
|
long _vsz = (_vfd >= 0) ? (long)lseek(_vfd, 0, SEEK_END) : -1L;
|
||||||
|
if (_vfd >= 0) close(_vfd);
|
||||||
|
printf("[EVT] snap: verify %s lseek=%ld\n", out_path, _vsz);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("[EVT] snap: ProcessOneFrame failed (%d) — upload will proceed without image\n", jpeg_size);
|
printf("[EVT] snap: ProcessOneFrame failed (%d) — upload will proceed without image\n", jpeg_size);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -318,7 +318,11 @@ int loadConfig(HOST_STREAM_INIT_OPT_T* pHostStreamInit)
|
|||||||
printf("[BT] WARNING: sed INI update returned %d (%s)\n", rc, HOST_STREAM_CONFIG_PATH);
|
printf("[BT] WARNING: sed INI update returned %d (%s)\n", rc, HOST_STREAM_CONFIG_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
event_recorder_init(ev_up, ev_sd, ev_max_mb, ev_delay, ev_enable, device_id, ev_dev);
|
int ev_spd_normal = iniparser_getint(ini, "can:speed_normal", 240);
|
||||||
|
int ev_spd_alert = iniparser_getint(ini, "can:speed_alert", 35);
|
||||||
|
int ev_spd_stop = iniparser_getint(ini, "can:speed_stop", 10);
|
||||||
|
event_recorder_init(ev_up, ev_sd, ev_max_mb, ev_delay, ev_enable, device_id, ev_dev,
|
||||||
|
ev_spd_normal, ev_spd_alert, ev_spd_stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- [can] section: MCP2515 CAN bus via J15 SPI connector --- */
|
/* --- [can] section: MCP2515 CAN bus via J15 SPI connector --- */
|
||||||
|
|||||||
@ -595,28 +595,22 @@ int mcp2515_reset(mcp2515_dev *mcp2515_device)
|
|||||||
// Set to configuration mode
|
// Set to configuration mode
|
||||||
uint8_t zeros[14];
|
uint8_t zeros[14];
|
||||||
memset(zeros, 0, sizeof(zeros));
|
memset(zeros, 0, sizeof(zeros));
|
||||||
printf("mcp2515 clean MCP_TXBXCTRL\n");
|
|
||||||
mcp2515_write_register(mcp2515_device,MCP_TXB0CTRL, zeros, 14);
|
mcp2515_write_register(mcp2515_device,MCP_TXB0CTRL, zeros, 14);
|
||||||
mcp2515_write_register(mcp2515_device,MCP_TXB1CTRL, zeros, 14);
|
mcp2515_write_register(mcp2515_device,MCP_TXB1CTRL, zeros, 14);
|
||||||
mcp2515_write_register(mcp2515_device,MCP_TXB2CTRL, zeros, 14);
|
mcp2515_write_register(mcp2515_device,MCP_TXB2CTRL, zeros, 14);
|
||||||
printf("mcp2515 clean MCP_RXBXCTRL\n");
|
|
||||||
mcp2515_write_register_once(mcp2515_device,MCP_RXB0CTRL, 0);
|
mcp2515_write_register_once(mcp2515_device,MCP_RXB0CTRL, 0);
|
||||||
mcp2515_write_register_once(mcp2515_device,MCP_RXB1CTRL, 0);
|
mcp2515_write_register_once(mcp2515_device,MCP_RXB1CTRL, 0);
|
||||||
printf("mcp2515 clean MCP_CANINTE\n");
|
|
||||||
mcp2515_write_register_once(mcp2515_device, MCP_CANINTE,
|
mcp2515_write_register_once(mcp2515_device, MCP_CANINTE,
|
||||||
CANINTF_RX0IF | CANINTF_RX1IF | CANINTF_ERRIF | CANINTF_MERRF);
|
CANINTF_RX0IF | CANINTF_RX1IF | CANINTF_ERRIF | CANINTF_MERRF);
|
||||||
printf("mcp2515 clean MCP_RXB0CTRL\n");
|
|
||||||
mcp2515_modify_bit(mcp2515_device, MCP_RXB0CTRL,
|
mcp2515_modify_bit(mcp2515_device, MCP_RXB0CTRL,
|
||||||
RXBnCTRL_RXM_MASK | RXB0CTRL_BUKT | RXB0CTRL_FILHIT_MASK,
|
RXBnCTRL_RXM_MASK | RXB0CTRL_BUKT | RXB0CTRL_FILHIT_MASK,
|
||||||
RXBnCTRL_RXM_STDEXT | RXB0CTRL_BUKT | RXB0CTRL_FILHIT);
|
RXBnCTRL_RXM_STDEXT | RXB0CTRL_BUKT | RXB0CTRL_FILHIT);
|
||||||
printf("mcp2515 clean MCP_RXB1CTRL\n");
|
|
||||||
mcp2515_modify_bit(mcp2515_device,MCP_RXB1CTRL,
|
mcp2515_modify_bit(mcp2515_device,MCP_RXB1CTRL,
|
||||||
RXBnCTRL_RXM_MASK | RXB1CTRL_FILHIT_MASK,
|
RXBnCTRL_RXM_MASK | RXB1CTRL_FILHIT_MASK,
|
||||||
RXBnCTRL_RXM_STDEXT | RXB1CTRL_FILHIT);
|
RXBnCTRL_RXM_STDEXT | RXB1CTRL_FILHIT);
|
||||||
// clear filters and masks
|
// clear filters and masks
|
||||||
// do not filter any standard frames for RXF0 used by RXB0
|
// do not filter any standard frames for RXF0 used by RXB0
|
||||||
// do not filter any extended frames for RXF1 used by RXB1
|
// do not filter any extended frames for RXF1 used by RXB1
|
||||||
printf("mcp2515 clean RXF\n");
|
|
||||||
RXF filters[] = {RXF0, RXF1, RXF2, RXF3, RXF4, RXF5};
|
RXF filters[] = {RXF0, RXF1, RXF2, RXF3, RXF4, RXF5};
|
||||||
int i=0;
|
int i=0;
|
||||||
for (i=0; i<6; i++) {
|
for (i=0; i<6; i++) {
|
||||||
@ -1027,22 +1021,18 @@ void mcp2515_modify_bit(mcp2515_dev *mcp2515_device, uint8_t register_address, u
|
|||||||
}
|
}
|
||||||
int mcp2515_sendMessage(mcp2515_dev *mcp2515_device, uint32_t can_id, uint8_t* data, uint8_t data_length)
|
int mcp2515_sendMessage(mcp2515_dev *mcp2515_device, uint32_t can_id, uint8_t* data, uint8_t data_length)
|
||||||
{
|
{
|
||||||
//printf("%s: func:%s,line:%d \n", __FILE__, __func__,__LINE__);
|
|
||||||
if (data_length > 8) {
|
if (data_length > 8) {
|
||||||
return ERROR_FAILTX;
|
return ERROR_FAILTX;
|
||||||
}
|
}
|
||||||
TXBn txBuffers[N_TXBUFFERS] = {TXB0, TXB1, TXB2};
|
TXBn txBuffers[N_TXBUFFERS] = {TXB0, TXB1, TXB2};
|
||||||
int i=0;
|
int i=0;
|
||||||
for (i=0; i<N_TXBUFFERS; i++) {
|
for (i=0; i<N_TXBUFFERS; i++) {
|
||||||
//printf("i : %d\n",i);
|
|
||||||
const struct TXBn_REGS *txbuf = &TXB[txBuffers[i]];
|
const struct TXBn_REGS *txbuf = &TXB[txBuffers[i]];
|
||||||
uint8_t ctrlval = mcp2515_read_register_once(mcp2515_device, txbuf->CTRL);
|
uint8_t ctrlval = mcp2515_read_register_once(mcp2515_device, txbuf->CTRL);
|
||||||
if ( (ctrlval & TXB_TXREQ) == 0 ) {
|
if ( (ctrlval & TXB_TXREQ) == 0 ) {
|
||||||
printf("Send Message: %x\n",txbuf->CTRL);
|
|
||||||
return mcp2515_sendMessageT(mcp2515_device,txBuffers[i], can_id, data, data_length);
|
return mcp2515_sendMessageT(mcp2515_device,txBuffers[i], can_id, data, data_length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//printf("%s: func:%s,line:%d \n", __FILE__, __func__,__LINE__);
|
|
||||||
return ERROR_ALLTXBUSY;
|
return ERROR_ALLTXBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1051,13 +1041,6 @@ int mcp2515_sendMessageT(mcp2515_dev *mcp2515_device, const TXBn txbn, uint32_t
|
|||||||
if (data_length > 8) {
|
if (data_length > 8) {
|
||||||
return ERROR_FAILTX;
|
return ERROR_FAILTX;
|
||||||
}
|
}
|
||||||
printf("%x %x ",can_id,data_length);
|
|
||||||
int i=0;
|
|
||||||
for(i=0;i<data_length;i++)
|
|
||||||
{
|
|
||||||
printf("0x%x ",data[i]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
const struct TXBn_REGS *txbuf = &TXB[txbn];
|
const struct TXBn_REGS *txbuf = &TXB[txbn];
|
||||||
|
|
||||||
uint8_t data1[13];
|
uint8_t data1[13];
|
||||||
@ -1097,7 +1080,7 @@ int mcp2515_sendMessageT(mcp2515_dev *mcp2515_device, const TXBn txbn, uint32_t
|
|||||||
uint8_t ctrl = mcp2515_read_register_once(mcp2515_device,txbuf->CTRL);
|
uint8_t ctrl = mcp2515_read_register_once(mcp2515_device,txbuf->CTRL);
|
||||||
|
|
||||||
if ((ctrl & (TXB_ABTF | TXB_MLOA)) != 0) {
|
if ((ctrl & (TXB_ABTF | TXB_MLOA)) != 0) {
|
||||||
printf("ERROR\n");
|
//printf("ERROR\n");
|
||||||
return ERROR_FAILTX;
|
return ERROR_FAILTX;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1107,10 +1090,10 @@ int mcp2515_sendMessageT(mcp2515_dev *mcp2515_device, const TXBn txbn, uint32_t
|
|||||||
|
|
||||||
if ((ctrl & TXB_TXREQ) == 0) {
|
if ((ctrl & TXB_TXREQ) == 0) {
|
||||||
if (saw_txerr) {
|
if (saw_txerr) {
|
||||||
printf("ERROR\n");
|
//printf("ERROR\n");
|
||||||
return ERROR_FAILTX;
|
return ERROR_FAILTX;
|
||||||
}
|
}
|
||||||
printf("OK\n");
|
//printf("OK\n");
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user