|
20 | 20 | #include "led_driver.h" |
21 | 21 | #include "motion_config.h" |
22 | 22 | #include "msg_queue.h" |
| 23 | +#include "pdc_buffer.h" |
| 24 | +#include "odometer.h" |
23 | 25 |
|
24 | 26 | #include <string.h> |
25 | 27 |
|
@@ -114,6 +116,8 @@ static uint8_t i2c_list[10] = {0}; |
114 | 116 | static uint8_t i2c_data[0xff] = {0}; |
115 | 117 | static uint32_t last_fsync_count = 0; |
116 | 118 | static uint32_t last_lsync_count = 0; |
| 119 | +static uint32_t last_system_odo = 0; |
| 120 | +static uint32_t last_laser_odo = 0; |
117 | 121 |
|
118 | 122 | static float tecadc_last_volts[4]; |
119 | 123 | static uint16_t tecadc_last_raw[4]; |
@@ -497,6 +501,68 @@ static _Bool process_controller_command(UartPacket *uartResp, UartPacket *cmd) |
497 | 501 | uartResp->data_len = (uint16_t)sizeof(pdu_frame); |
498 | 502 | uartResp->data = pdu_frame.bytes; |
499 | 503 | break; |
| 504 | + case OW_CTRL_GET_PDC_BUFFER: { |
| 505 | + uartResp->command = OW_CTRL_GET_PDC_BUFFER; |
| 506 | + uartResp->addr = cmd->addr; |
| 507 | + uartResp->reserved = cmd->reserved; |
| 508 | + |
| 509 | + /* Request payload: 1 byte = max_samples (clamped to 64). */ |
| 510 | + uint8_t requested = (cmd->data_len >= 1) ? cmd->data[0] : 64; |
| 511 | + if (requested == 0 || requested > 64) requested = 64; |
| 512 | + |
| 513 | + /* Response layout: [dropped:u16 LE][count:u8][count * sizeof(pdc_sample_t)] */ |
| 514 | + static pdc_sample_t drained[64]; |
| 515 | + size_t n = pdc_buffer_drain(drained, requested); |
| 516 | + uint16_t dropped = pdc_buffer_dropped_since_last_drain(); |
| 517 | + |
| 518 | + static uint8_t resp[3 + 64 * sizeof(pdc_sample_t)]; |
| 519 | + resp[0] = (uint8_t)(dropped & 0xFF); |
| 520 | + resp[1] = (uint8_t)((dropped >> 8) & 0xFF); |
| 521 | + resp[2] = (uint8_t)n; |
| 522 | + memcpy(&resp[3], drained, n * sizeof(pdc_sample_t)); |
| 523 | + |
| 524 | + uartResp->data_len = (uint16_t)(3 + n * sizeof(pdc_sample_t)); |
| 525 | + uartResp->data = resp; |
| 526 | + } break; |
| 527 | + case OW_CTRL_GET_SYSTEM_ODO: |
| 528 | + uartResp->command = OW_CTRL_GET_SYSTEM_ODO; |
| 529 | + uartResp->addr = cmd->addr; |
| 530 | + uartResp->reserved = cmd->reserved; |
| 531 | + uartResp->data_len = 4; |
| 532 | + last_system_odo = Odometer_Get_System_Minutes(); |
| 533 | + uartResp->data = (uint8_t *)&last_system_odo; |
| 534 | + break; |
| 535 | + case OW_CTRL_GET_LASER_ODO: |
| 536 | + uartResp->command = OW_CTRL_GET_LASER_ODO; |
| 537 | + uartResp->addr = cmd->addr; |
| 538 | + uartResp->reserved = cmd->reserved; |
| 539 | + uartResp->data_len = 4; |
| 540 | + last_laser_odo = Odometer_Get_Laser_Pulses(); |
| 541 | + uartResp->data = (uint8_t *)&last_laser_odo; |
| 542 | + break; |
| 543 | + case OW_CTRL_RESET_ODO: { |
| 544 | + uartResp->command = OW_CTRL_RESET_ODO; |
| 545 | + uartResp->addr = cmd->addr; |
| 546 | + uartResp->reserved = cmd->reserved; |
| 547 | + /* Request payload: 1 byte = target (0=system, 1=laser, 2=both). |
| 548 | + * No payload defaults to "both" for caller convenience. */ |
| 549 | + OdoResetTarget target = ODO_RESET_BOTH; |
| 550 | + if (cmd->data_len >= 1) { |
| 551 | + if (cmd->data[0] > (uint8_t)ODO_RESET_BOTH) { |
| 552 | + uartResp->data_len = 0; |
| 553 | + uartResp->packet_type = OW_ERROR; |
| 554 | + break; |
| 555 | + } |
| 556 | + target = (OdoResetTarget)cmd->data[0]; |
| 557 | + } |
| 558 | + static uint8_t reset_resp; |
| 559 | + reset_resp = (Odometer_Reset(target) == HAL_OK) ? 0 : 1; |
| 560 | + uartResp->data_len = 1; |
| 561 | + uartResp->data = &reset_resp; |
| 562 | + if (reset_resp != 0) { |
| 563 | + uartResp->packet_type = OW_ERROR; |
| 564 | + } |
| 565 | + } break; |
500 | 566 | default: |
501 | 567 | uartResp->data_len = 0; |
502 | 568 | uartResp->packet_type = OW_UNKNOWN; |
|
0 commit comments