main
TylerK Update 20 file(s) fb8969c 1mo ago
#include "uart_telemetry.h"
#include "main.h"   /* CubeMX-generated: huart1 handle */
#include <stdio.h>
#include <string.h>

static const char *state_name(charge_state_t s) {
    switch (s) {
    case CHG_STATE_BULK:       return "BULK";
    case CHG_STATE_ABSORPTION: return "ABSORPTION";
    case CHG_STATE_FLOAT:      return "FLOAT";
    case CHG_STATE_FAULT:      return "FAULT";
    default:                   return "?";
    }
}

/* Cortex-M0+ newlib-nano builds commonly ship without float printf support
 * (it costs several KB of flash on a part with only 64KB total) -- format
 * manually in millivolts/milliamps instead of linking a float formatter. */
static int fmt_milli(char *buf, int32_t milli) {
    /* The sign has to be emitted separately. Integer division truncates
     * toward zero, so for anything between -999 and -1 the whole part is 0
     * and carries no sign of its own -- printing whole.frac would turn
     * -0.250A of discharge into "0.250", reporting a battery that is being
     * drained as one that is being charged. */
    const char *sign = (milli < 0) ? "-" : "";
    int32_t mag = (milli < 0) ? -milli : milli;
    return sprintf(buf, "%s%ld.%03ld", sign, (long)(mag / 1000), (long)(mag % 1000));
}

void uart_telemetry_init(void) {
    /* huart1 is brought up by CubeMX's MX_USART1_UART_Init(); nothing
     * additional needed here. */
}

void uart_telemetry_send(uint32_t now_ms, const sensor_frame_t *s, const charge_control_t *cc) {
    char line[160];
    char vbatt_s[16], iin_s[16], ichg_s[16], cmd_s[16];

    fmt_milli(vbatt_s, (int32_t)(s->vbatt * 1000.0f));
    fmt_milli(iin_s, (int32_t)(s->iin * 1000.0f));
    fmt_milli(ichg_s, (int32_t)(s->ichg * 1000.0f));
    fmt_milli(cmd_s, (int32_t)(cc->commanded_vbatt * 1000.0f));

    int n = snprintf(line, sizeof(line),
        "t=%lu state=%s vbatt=%sV iin=%sA ichg=%sA cmd=%sV reason=%s pgood=%d,%d\r\n",
        (unsigned long)now_ms, state_name(cc->state),
        vbatt_s, iin_s, ichg_s, cmd_s, cc->limiting_reason,
        s->bias_pgood, s->mppt_pgood);

    if (n > 0) {
        HAL_UART_Transmit(&huart1, (uint8_t *)line, (uint16_t)n, 20);
    }
}