ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_doc.c
Go to the documentation of this file.
1
24
25#include "ra8_doc.h"
26
27#include <stdint.h>
28
29#include "ra8_attributes.h"
30#include "ra8_check.h"
31#include "ra8_doc_regs.h"
32#include "ra8_err.h"
33#include "ra8_log.h"
34#include "ra8_mstp.h"
35
36static const char* s_tag = "DOC";
37
55{
56 volatile r_doc_regs_t* reg = ra8_doc();
57 /* Write OMS field, clear DOBW + DCSEL. */
58 /* HUM Ch 57.2.1 "DOCR : DOC Control Register" p 3519 */
59 reg->DOCR = (uint8_t)mode;
60}
61
87RA8_INTERNAL static inline uint16_t internal_ra8_doc_run_16(uint16_t seed, uint16_t operand)
88{
89 volatile r_doc_regs_t* reg = ra8_doc();
90 volatile uint16_t* dodsr0 = (volatile uint16_t*)&reg->DODSR0;
91 volatile uint16_t* dodir = (volatile uint16_t*)&reg->DODIR;
92 /* Seed the accumulator first. */
93 /* HUM Ch 57.2.5 "DODSR0 : DOC Data Setting Register 0" p 3521 */
94 *dodsr0 = seed;
95 /* Writing DODIR triggers the operation. */
96 /* HUM Ch 57.2.4 "DODIR : DOC Data Input Register" p 3521 */
97 *dodir = operand;
98 /* Read back the accumulator the operation just updated. */
99 /* HUM Ch 57.2.5 "DODSR0 : DOC Data Setting Register 0" p 3521 */
100 return *dodsr0;
101}
102
103[[nodiscard]] ra8_err_t ra8_doc_init(void)
104{
105 /* HUM Ch 11.2.8 "MSTPCRC : Module Stop Control Register C", p 447 */
107 /* GCOVR_EXCL_BR_START -- MSTP HW readback */
108 RA8_RETURN_ON_ERROR(mst_err, s_tag, "doc_init: mstp enable");
109 /* GCOVR_EXCL_BR_STOP */
110
111 volatile r_doc_regs_t* reg = ra8_doc();
112 /* Reset DOCR to default (compare/16-bit). */
113 /* HUM Ch 57.2.1 "DOCR : DOC Control Register" p 3519 */
114 reg->DOCR = 0U;
115 /* Clear any stale DOPCF via DOSCR.DOPCFCL. */
116 /* HUM Ch 57.2.3 "DOSCR : DOC Status Clear Register" p 3521 */
117 reg->DOSCR = (uint8_t)k_ra8_doc_mask_dopcfcl;
118 /* Zero the data registers (DODIR, DODSR0, DODSR1). */
119 /* HUM Ch 57.2.4 "DODIR : DOC Data Input Register" p 3521 */
120 reg->DODIR = 0U;
121 reg->DODSR0 = 0U;
122 reg->DODSR1 = 0U;
123 ra8_log_info(s_tag, "doc_init");
124 return k_ra8_ok;
125}
126
127[[nodiscard]] ra8_err_t ra8_doc_add16(uint16_t a, uint16_t b, uint16_t* out_sum)
128{
129 RA8_CHECK_NULL_PTR(out_sum, s_tag, "out_sum must not be nullptr");
130
132 *out_sum = internal_ra8_doc_run_16(a, b);
133 return k_ra8_ok;
134}
135
136[[nodiscard]] ra8_err_t ra8_doc_sub16(uint16_t a, uint16_t b, uint16_t* out_diff)
137{
138 RA8_CHECK_NULL_PTR(out_diff, s_tag, "out_diff must not be nullptr");
139
141 *out_diff = internal_ra8_doc_run_16(a, b);
142 return k_ra8_ok;
143}
144
145/* =============================================================================
146 * Window comparison
147 * =============================================================================
148 */
149
151[[nodiscard]] ra8_err_t
152ra8_doc_set_window(uint16_t lower, uint16_t upper, ra8_doc_window_polarity_t polarity)
153{
154 if (lower >= upper) {
155 ra8_log_error(s_tag, "set_window: lower must be strictly less than upper");
157 }
158 if ((uint8_t)polarity > (uint8_t)k_ra8_doc_window_outside) {
159 ra8_log_error(s_tag, "set_window: polarity out of range");
161 }
162
163 volatile r_doc_regs_t* reg = ra8_doc();
164 volatile uint16_t* dodsr0 = (volatile uint16_t*)&reg->DODSR0;
165 volatile uint16_t* dodsr1 = (volatile uint16_t*)&reg->DODSR1;
166 uint8_t dcsel;
167
168 if (polarity == k_ra8_doc_window_outside) {
169 dcsel = (uint8_t)k_ra8_doc_dcsel_outside;
170 } else {
171 dcsel = (uint8_t)k_ra8_doc_dcsel_inside;
172 }
173
174 /* OMS=00 (compare), DOBW=0 (16-bit), DCSEL=inside(4) or outside(5). */
175 /* HUM Ch 57.2.1 "DOCR : DOC Control Register" p 3519 */
176 reg->DOCR =
177 (uint8_t)((uint8_t)(dcsel << (uint8_t)k_ra8_doc_bit_dcsel) & (uint8_t)k_ra8_doc_mask_dcsel);
178 /* Lower threshold; the constraint DODSR1 > DODSR0 is caller-validated. */
179 /* HUM Ch 57.2.5 "DODSR0 : DOC Data Setting Register 0" p 3521 */
180 *dodsr0 = lower;
181 /* Upper threshold; only used in window comparison mode. */
182 /* HUM Ch 57.2.6 "DODSR1 : DOC Data Setting Register 1" p 3522 */
183 *dodsr1 = upper;
184 /* Clear any stale DOPCF so the first compare sees a fresh flag. */
185 /* HUM Ch 57.2.3 "DOSCR : DOC Status Clear Register" p 3521 */
186 reg->DOSCR = (uint8_t)k_ra8_doc_mask_dopcfcl;
187
188 ra8_log_info(s_tag, "set_window");
189 return k_ra8_ok;
190}
191
193[[nodiscard]] ra8_err_t ra8_doc_window_compare(uint16_t value, bool* out_flag)
194{
195 RA8_CHECK_NULL_PTR(out_flag, s_tag, "out_flag must not be nullptr");
196
197 volatile r_doc_regs_t* reg = ra8_doc();
198 /* Precondition: OMS must be 00 (compare mode); set_window() enforces this. */
199 /* HUM Ch 57.2.1 "DOCR : DOC Control Register" p 3519 */
200 if ((reg->DOCR & (uint8_t)k_ra8_doc_mask_oms) != 0U) {
201 ra8_log_error(s_tag, "window_compare: DOC not in compare mode");
203 }
204
205 volatile uint16_t* dodir = (volatile uint16_t*)&reg->DODIR;
206 /* Clear any prior flag before triggering a new comparison. */
207 /* HUM Ch 57.2.3 "DOSCR : DOC Status Clear Register" p 3521 */
208 reg->DOSCR = (uint8_t)k_ra8_doc_mask_dopcfcl;
209 /* Writing DODIR triggers the hardware comparison; DOSR.DOPCF is set.
210 * The RAM-backed host register file has no comparator engine, so on
211 * the unit-test build DOSR simply retains whatever the test staged
212 * before the call -- both flag legs below are driven that way. */
213 /* HUM Ch 57.2.4 "DODIR : DOC Data Input Register" p 3521 */
214 *dodir = value;
215
216 /* Read DOPCF -- set by the silicon comparator after the compare. */
217 /* HUM Ch 57.2.2 "DOSR : DOC Flag Status Register" p 3520 */
218 *out_flag = ((reg->DOSR & (uint8_t)k_ra8_doc_mask_dopcf) != 0U);
219 /* Clear DOPCF so the flag reflects only the last comparison. */
220 /* HUM Ch 57.2.3 "DOSCR : DOC Status Clear Register" p 3521 */
221 reg->DOSCR = (uint8_t)k_ra8_doc_mask_dopcfcl;
222
223 return k_ra8_ok;
224}
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_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
Definition ra8_check.h:184
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
static void internal_ra8_doc_set_mode_16(ra8_docr_oms_t mode)
Write mode into DOCR.OMS[1:0], clearing DOBW for 16-bit ops.
Definition ra8_doc.c:54
ra8_err_t ra8_doc_add16(uint16_t a, uint16_t b, uint16_t *out_sum)
Perform a 16-bit hardware add.
Definition ra8_doc.c:127
static uint16_t internal_ra8_doc_run_16(uint16_t seed, uint16_t operand)
Run the 16-bit DOC operation sequence and return the result.
Definition ra8_doc.c:87
ra8_err_t ra8_doc_sub16(uint16_t a, uint16_t b, uint16_t *out_diff)
Perform a 16-bit hardware subtract.
Definition ra8_doc.c:136
ra8_err_t ra8_doc_window_compare(uint16_t value, bool *out_flag)
Implementation of ra8_doc_window_compare() – writes DODIR, reads DOPCF.
Definition ra8_doc.c:193
ra8_err_t ra8_doc_set_window(uint16_t lower, uint16_t upper, ra8_doc_window_polarity_t polarity)
Implementation of ra8_doc_set_window() – programs DOCR/DODSR0/DODSR1.
Definition ra8_doc.c:152
ra8_err_t ra8_doc_init(void)
Reset the DOC control register to its reset state.
Definition ra8_doc.c:103
Data Operation Circuit (DOC) driver header.
ra8_doc_window_polarity_t
Window-comparison polarity for ra8_doc_set_window().
Definition ra8_doc.h:93
@ k_ra8_doc_window_outside
Flag when DODIR < DODSR0 or DODSR1 < DODIR.
Definition ra8_doc.h:95
Data Operation Circuit (DOC) register layout for the Renesas RA8D2.
@ k_ra8_doc_mask_dopcf
Data-operation circuit flag.
ra8_docr_oms_t
Operation-mode codes written to DOCR.OMS[1:0] (HUM 57.2.1 p 3519).
@ k_ra8_doc_mode_add
Add of DODIR into DODSR0.
@ k_ra8_doc_mode_subtract
Subtract of DODIR from DODSR0.
static volatile r_doc_regs_t * ra8_doc(void)
Get a pointer to the DOC register block.
@ k_ra8_doc_bit_dcsel
Detection condition select bit 0.
@ k_ra8_doc_mask_oms
OMS[1:0] field mask.
@ k_ra8_doc_mask_dcsel
DCSEL[2:0] field mask in DOCR (bits 6:4).
@ k_ra8_doc_mask_dopcfcl
Write 1 to clear DOPCF.
@ k_ra8_doc_dcsel_inside
Set DOPCF when DODSR0 < DODIR < DODSR1 (inside window).
@ k_ra8_doc_dcsel_outside
Set DOPCF when DODIR < DODSR0 or DODSR1 < DODIR (outside).
Error Code Definitions for ra8-firmware.
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
Definition ra8_err.h:161
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_info(tag, message)
RA8 log info.
Definition ra8_log.h:364
#define ra8_log_error(tag, message)
RA8 log error.
Definition ra8_log.h:335
Ref-counted Module Stop Control wrapper for the RA8D2.
ra8_err_t ra8_mstp_enable(ra8_mstp_t id)
Reference-counted "ungate this peripheral" request.
Definition ra8_mstp.c:343
@ k_ra8_mstp_doc
MSTPC13 DOC.
DOC_B register window (HUM Ch 57.2 p 3519-3522).
volatile uint32_t DODSR1
+0x14 Upper window threshold.
volatile uint32_t DODIR
+0x0C Data input (access at DOBW width).
volatile uint8_t DOSR
+0x04 Status flag (DOPCF).
volatile uint8_t DOSCR
+0x08 Status clear (DOPCFCL, write-only).
volatile uint32_t DODSR0
+0x10 Reference / running result.
volatile uint8_t DOCR
+0x00 Control (mode, width, DCSEL).