diff --git a/traceX/inc/traceout.h b/traceX/inc/traceout.h new file mode 100644 index 00000000..25efcfd8 --- /dev/null +++ b/traceX/inc/traceout.h @@ -0,0 +1,41 @@ +/** + * @file traceout.h + * @brief TraceX data output interface. + */ + +#ifndef TRACEOUT_H +#define TRACEOUT_H + +#include + +/* Size of each transmitted chunk */ +#define TRACEOUT_CHUNK_BYTES (1024U) + +/** + * @brief Platform transmit callback. + * + * Must initiate a non-blocking transmit (DMA / IT). + * + * @param data Pointer to data buffer. + * @param len Number of bytes to transmit. + */ +typedef void (*traceout_tx_fn_t)(const uint8_t *data, uint16_t len); + +/** + * @brief Initialize trace output streaming. + * + * @param tx_fn Platform transmit callback. + */ +void traceout_init(traceout_tx_fn_t tx_fn); + +/** + * @brief Start trace output from ISR context. + */ +void traceout_start_from_isr(void); + +/** + * @brief Notify trace output that transmit completed (ISR context). + */ +void traceout_on_tx_complete_from_isr(void); + +#endif /* TRACEOUT_H */ \ No newline at end of file diff --git a/traceX/inc/tracex.h b/traceX/inc/tracex.h new file mode 100644 index 00000000..b472c16d --- /dev/null +++ b/traceX/inc/tracex.h @@ -0,0 +1,51 @@ +/** + * @file tracex.h + * @brief TraceX control interface. + * + */ + +#ifndef TRACEX_H +#define TRACEX_H + +#include "tx_api.h" +#include + +/** + * @brief Initialize TraceX with a user-provided buffer. + * + * This must be called once before starting TraceX. + * + * @param buffer Pointer to trace buffer. + * @param size Size of trace buffer in bytes. + */ +void tracex_init(UCHAR *buffer, uint32_t size); + +/** + * @brief Start TraceX recording. + * + * Safe to call multiple times. + */ +void tracex_start(void); + +/** + * @brief Stop TraceX recording. + * + * Safe to call multiple times. + */ +void tracex_stop(void); + +/** + * @brief Get the TraceX buffer pointer. + * + * @return Pointer to trace buffer. + */ +UCHAR *tracex_get_buffer(void); + +/** + * @brief Get the TraceX buffer size. + * + * @return Buffer size in bytes. + */ +uint32_t tracex_get_buffer_size(void); + +#endif /* TRACEX_H */ \ No newline at end of file diff --git a/traceX/src/traceout.c b/traceX/src/traceout.c new file mode 100644 index 00000000..d7dab394 --- /dev/null +++ b/traceX/src/traceout.c @@ -0,0 +1,56 @@ +/** + * @file traceout.c + * @brief TraceX data output interface. + */ + +#include "traceout.h" +#include "tracex.h" + +static traceout_tx_fn_t s_tx_fn = NULL; +static volatile uint8_t s_output_active = 0U; +static const uint8_t *s_dp = NULL; +static uint32_t s_remaining = 0U; + +static void start_next_chunk(void) +{ + if (s_remaining == 0U) { + s_output_active = 0U; + tracex_start(); + return; + } + + uint32_t n = (s_remaining > TRACEOUT_CHUNK_BYTES) ? + TRACEOUT_CHUNK_BYTES : + s_remaining; + + s_tx_fn(s_dp, (uint16_t)n); + s_dp += n; + s_remaining -= n; +} + +void traceout_init(traceout_tx_fn_t tx_fn) +{ + s_tx_fn = tx_fn; +} + +void traceout_start_from_isr(void) +{ + if ((s_tx_fn == NULL) || (s_output_active != 0U)) { + return; + } + + tracex_stop(); + + s_dp = tracex_get_buffer(); + s_remaining = tracex_get_buffer_size(); + s_output_active = 1U; + + start_next_chunk(); +} + +void traceout_on_tx_complete_from_isr(void) +{ + if (s_output_active != 0U) { + start_next_chunk(); + } +} \ No newline at end of file diff --git a/traceX/src/tracex.c b/traceX/src/tracex.c new file mode 100644 index 00000000..08732ced --- /dev/null +++ b/traceX/src/tracex.c @@ -0,0 +1,49 @@ +/** + * @file tracex.c + * @brief TraceX control interface. + * + */ + +#include "tracex.h" +#include + +static UCHAR *s_trace_buffer = NULL; +static uint32_t s_trace_size = 0U; +static bool s_tracex_started = false; + +void tracex_init(UCHAR *buffer, uint32_t size) +{ + s_trace_buffer = buffer; + s_trace_size = size; +} + +UCHAR *tracex_get_buffer(void) +{ + return s_trace_buffer; +} + +uint32_t tracex_get_buffer_size(void) +{ + return s_trace_size; +} + +void tracex_start(void) +{ + if ((s_tracex_started == true) || (s_trace_buffer == NULL) || + (s_trace_size == 0U)) { + return; + } + + tx_trace_enable(s_trace_buffer, s_trace_size, 32U); + s_tracex_started = true; +} + +void tracex_stop(void) +{ + if (s_tracex_started == false) { + return; + } + + tx_trace_disable(); + s_tracex_started = false; +} \ No newline at end of file