ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_io_stream.c
Go to the documentation of this file.
1
17
18#include "ra8_io_stream.h"
19
20#include <stddef.h>
21#include <stdint.h>
22
23#include "ra8_attributes.h"
24#include "ra8_check.h"
25#include "ra8_err.h"
27
29static const char* const s_tag = "ra8_io_stream";
30
45
70{
71 if (s == nullptr) {
72 return k_ra8_err_null_ptr;
73 }
74 if (s->iface == nullptr) {
76 }
77 return k_ra8_ok;
78}
79
81ra8_io_stream_bind(ra8_io_stream_t* stream, const ra8_io_stream_iface_t* iface, void* context)
82{
83 if ((stream == nullptr) || (iface == nullptr) || (context == nullptr)) {
84 return k_ra8_err_null_ptr;
85 }
86 if (iface->write == nullptr) {
88 }
89 *stream = (ra8_io_stream_t){.iface = iface, .ctx = context};
90 return k_ra8_ok;
91}
92
94ra8_io_stream_write(ra8_io_stream_t* s, const uint8_t* buf, uint32_t len, uint32_t* out_written)
95{
96 const ra8_err_t v = internal_validate(s);
97 if (v != k_ra8_ok) {
98 return v;
99 }
100 RA8_CHECK_NULL_PTR(buf, s_tag, "buf must not be nullptr");
101 RA8_CHECK_NULL_PTR(s->iface->write, s_tag, "sink write op missing");
102 uint32_t accepted = 0U;
103 const ra8_err_t error = s->iface->write(s->ctx, buf, len, &accepted);
104 if (accepted > len) {
106 }
107 if (out_written != nullptr) {
108 *out_written = accepted;
109 }
110 if ((error == k_ra8_ok) && (accepted != len)) {
112 }
113 return error;
114}
115
117{
118 const ra8_err_t v = internal_validate(s);
119 if (v != k_ra8_ok) {
120 return v;
121 }
122 if (s->iface->flush == nullptr) {
123 return k_ra8_ok;
124 }
125 return s->iface->flush(s->ctx);
126}
127
129{
130 const ra8_err_t v = internal_validate(s);
131 if (v != k_ra8_ok) {
132 return v;
133 }
134 const uint8_t b = (uint8_t)c;
135 return ra8_io_stream_write(s, &b, 1U, nullptr);
136}
137
139{
140 const ra8_err_t v = internal_validate(s);
141 if (v != k_ra8_ok) {
142 return v;
143 }
144 RA8_CHECK_NULL_PTR(str, s_tag, "str must not be nullptr");
145 uint32_t len = 0;
146 while (len < (uint32_t)k_ra8_io_puts_max) {
147 if (str[len] == '\0') {
148 return ra8_io_stream_write(s, (const uint8_t*)str, len, nullptr);
149 }
150 ++len;
151 }
153}
154
156{
157 const ra8_err_t v = internal_validate(s);
158 if (v != k_ra8_ok) {
159 return v;
160 }
161 uint8_t tmp[k_ra8_io_u32_max_digits];
162 uint32_t i = 0;
163 uint32_t x = value;
164 do {
165 tmp[i] = (uint8_t)('0' + (x % (uint32_t)k_ra8_io_dec_base));
166 x /= (uint32_t)k_ra8_io_dec_base;
167 ++i;
168 } while (x != 0U);
169 uint8_t out[k_ra8_io_u32_max_digits];
170 for (uint32_t j = 0; j < i; ++j) {
171 out[j] = tmp[i - 1U - j];
172 }
173 return ra8_io_stream_write(s, out, i, nullptr);
174}
175
177{
178 const ra8_err_t validation = internal_validate(s);
179 if (validation != k_ra8_ok) {
180 return validation;
181 }
182 uint8_t reversed[k_ra8_io_u64_max_digits];
183 uint32_t digits = 0U;
184 uint64_t remaining = value;
185 do {
186 reversed[digits] = (uint8_t)('0' + (remaining % (uint64_t)k_ra8_io_dec_base));
187 remaining /= (uint64_t)k_ra8_io_dec_base;
188 ++digits;
189 } while (remaining != 0U);
190 uint8_t output[k_ra8_io_u64_max_digits];
191 for (uint32_t index = 0U; index < digits; ++index) {
192 output[index] = reversed[digits - 1U - index];
193 }
194 return ra8_io_stream_write(s, output, digits, nullptr);
195}
196
197ra8_err_t ra8_io_stream_put_hex(ra8_io_stream_t* s, uint32_t value, uint8_t min_digits)
198{
199 const ra8_err_t v = internal_validate(s);
200 if (v != k_ra8_ok) {
201 return v;
202 }
203 if (min_digits == 0U) {
205 }
206 if (min_digits > (uint8_t)k_ra8_io_hex_max_digits) {
208 }
209 static const char k_hex[] = "0123456789abcdef";
210 uint8_t tmp[k_ra8_io_hex_max_digits];
211 uint32_t i = 0;
212 uint32_t x = value;
213 do {
214 tmp[i] = (uint8_t)k_hex[x % (uint32_t)k_ra8_io_hex_base];
215 x /= (uint32_t)k_ra8_io_hex_base;
216 ++i;
217 } while (x != 0U);
218 while (i < (uint32_t)min_digits) {
219 tmp[i] = (uint8_t)'0';
220 ++i;
221 }
222 uint8_t out[k_ra8_io_hex_max_digits];
223 for (uint32_t j = 0; j < i; ++j) {
224 out[j] = tmp[i - 1U - j];
225 }
226 return ra8_io_stream_write(s, out, i, nullptr);
227}
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
Error Code Definitions for ra8-firmware.
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_not_initialized
Module not initialized – _init() not yet called successfully.
Definition ra8_err.h:235
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
Definition ra8_err.h:478
@ k_ra8_err_protocol_error
Protocol-level error (e.g.
Definition ra8_err.h:429
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
Definition ra8_err.h:167
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
ra8_err_t ra8_io_stream_write(ra8_io_stream_t *s, const uint8_t *buf, uint32_t len, uint32_t *out_written)
Write len bytes to the bound sink.
ra8_err_t ra8_io_stream_puts(ra8_io_stream_t *s, const char *str)
Write a NUL-terminated string (without the NUL) to the bound sink.
ra8_err_t ra8_io_stream_put_u32(ra8_io_stream_t *s, uint32_t value)
Write value as unsigned decimal ASCII (no leading zeros).
ra8_err_t ra8_io_stream_bind(ra8_io_stream_t *stream, const ra8_io_stream_iface_t *iface, void *context)
Bind a backend vtable and caller-owned state into a stream handle.
ra8_err_t ra8_io_stream_flush(ra8_io_stream_t *s)
Flush any sink-side buffering to its destination.
ra8_err_t ra8_io_stream_put_u64(ra8_io_stream_t *s, uint64_t value)
Write value as unsigned 64-bit decimal ASCII without leading zeros.
ra8_err_t ra8_io_stream_putc(ra8_io_stream_t *s, char c)
Write a single byte to the bound sink.
ra8_io_stream_const_t
Rendering constants for the formatted-output helpers.
@ k_ra8_io_dec_base
Base for ra8_io_stream_put_u32.
@ k_ra8_io_hex_max_digits
Hex digits in a 32-bit value.
@ k_ra8_io_u64_max_digits
Decimal digits in UINT64_MAX.
@ k_ra8_io_puts_max
Bounded scan limit for ra8_io_stream_puts.
@ k_ra8_io_u32_max_digits
Decimal digits in UINT32_MAX.
@ k_ra8_io_hex_base
Base for ra8_io_stream_put_hex.
static ra8_err_t internal_validate(const ra8_io_stream_t *s)
Reject a handle that is NULL or has no sink bound.
ra8_err_t ra8_io_stream_put_hex(ra8_io_stream_t *s, uint32_t value, uint8_t min_digits)
Write value as lowercase hex ASCII, zero-padded to min_digits.
ra8_io targetable byte-stream facade – one writer, many destinations.
struct ra8_io_stream_iface ra8_io_stream_iface_t
Public implementer contract for ra8_io byte-stream backends.
ra8_err_t(* flush)(void *ctx)
Commit any buffering.
ra8_err_t(* write)(void *ctx, const uint8_t *buf, uint32_t len, uint32_t *out_written)
Write len bytes from buf, reporting the accepted count.
Caller-allocated byte-stream handle binding a sink to its context.
const ra8_io_stream_iface_t * iface
Bound sink vtable (private).
void * ctx
Sink-private context (private).