ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_tsn.c
Go to the documentation of this file.
1
17
18#include "ra8_tsn.h"
19
20#include <stdint.h>
21
22#include "ra8_adc.h"
23#include "ra8_attributes.h"
24#include "ra8_check.h"
25#include "ra8_err.h"
26#include "ra8_hw_intrinsics.h"
27#include "ra8_log.h"
28#include "ra8_mstp.h"
29#include "ra8_tsn_regs.h"
30
31static const char* s_tag = "TSN";
32
45typedef enum : uint16_t {
49
58
68
74
101static void internal_busy_wait_us(uint16_t usec)
102{
103 for (uint16_t u = 0U; u < usec; ++u) {
104 for (uint16_t i = 0U; i < k_ra8_tsn_busy_loops_per_us; ++i) {
105 ra8_hw_nop();
106 }
107 }
108}
109
130{
131 bool high_ok = false;
134 high_ok = true;
135 }
136 bool low_ok = false;
138 low_ok = true;
139 }
140 if (!high_ok || !low_ok) {
142 }
143 if (cfg->stab_us < k_ra8_tsn_min_stab_us) {
145 }
146 return k_ra8_ok;
147}
148
150{
151 RA8_CHECK_NULL_PTR(cfg, s_tag, "cfg must not be nullptr");
152 const ra8_err_t cfg_err = internal_validate_cfg(cfg);
153 RA8_RETURN_ON_ERROR(cfg_err, s_tag, "tsn_init: cfg invalid");
154
155 /* HUM Ch 11.2.9 "MSTPCRD : Module Stop Control Register D", p 449 */
157 /* GCOVR_EXCL_BR_START -- MSTP HW readback */
158 RA8_RETURN_ON_ERROR(mst_err, s_tag, "tsn_init: mstp enable");
159 /* GCOVR_EXCL_BR_STOP */
160
161 /* HUM Ch 55.2.1 "TSCR : Temperature Sensor Control Register", p 3498 */
162 volatile r_tsn_ctrl_regs_t* reg = ra8_tsn();
164
165 /* HUM Ch 55.3.2 "Procedures for Measuring Temperature Sensor", p 3502
166 * (tTSTBL = 30 us per Figure 55.2 -- wait before enabling output). */
168
169 /* HUM Ch 55.2.1 "TSCR : Temperature Sensor Control Register", p 3498 */
171
173 s_ra8_tsn_low_ref_degc = (int16_t)cfg->low_ref_degc;
175
176 ra8_log_info(s_tag, "tsn_init");
177 return k_ra8_ok;
178}
179
181{
182 /* HUM Ch 55.2.1 "TSCR : Temperature Sensor Control Register", p 3498 */
183 volatile r_tsn_ctrl_regs_t* reg = ra8_tsn();
184 /* HUM Ch 55.3.2 "Procedures for Measuring Temperature Sensor", p 3502
185 * (clear TSOE first, then TSEN). */
187 /* HUM Ch 55.2.1 "TSCR : Temperature Sensor Control Register", p 3498 */
188 reg->TSCR = 0U;
189
190 /* Clear the init flag unconditionally so that callers cannot reach a
191 * "looks-initialized but isn't" state if deinit is invoked from a
192 * partially-torn-down context (e.g. mstp refcount already 0 because
193 * the test harness reset it). The mstp refcount underflow is logged
194 * by ra8_mstp itself and is harmless here. */
195 s_ra8_tsn_initialized = false;
196
197 /* HUM Ch 11.2.9 "MSTPCRD : Module Stop Control Register D", p 449 */
199 return k_ra8_ok;
200}
201
202ra8_err_t ra8_tsn_read_raw(uint16_t raw, uint16_t* out_code)
203{
204 RA8_CHECK_NULL_PTR(out_code, s_tag, "out_code must not be nullptr");
207 }
208 /* HUM Ch 55.2.2 "TSCDR : Temperature Sensor Calibration Data Register",
209 * p 3498-3499 -- live samples share the 12-bit code width. */
210 *out_code = (uint16_t)(raw & k_ra8_tscdr_data_mask);
211 return k_ra8_ok;
212}
213
214ra8_err_t ra8_tsn_convert_to_milli_c(uint16_t raw_code, int32_t* out_milli_c)
215{
216 RA8_CHECK_NULL_PTR(out_milli_c, s_tag, "out_milli_c must not be nullptr");
219 }
220
221 /* HUM Ch 55.2.2 "TSCDR : Temperature Sensor Calibration Data Register", p 3498-3499 */
222 volatile const r_tsn_cal_regs_t* cal = ra8_tsn_cal();
223 const uint32_t cal_hi = cal->TSCDR & (uint32_t)k_ra8_tscdr_data_mask;
224 const uint32_t cal_lo = cal->TSCDR2 & (uint32_t)k_ra8_tscdr_data_mask;
225
226 if (cal_hi == cal_lo) {
227 /* Either an unprogrammed part or both trim words read 0; both
228 * mean "no slope is computable" and we must refuse rather than
229 * divide by zero (HUM Ch 55.3.1 p 3499). */
231 }
232
233 /* All math in 64-bit signed integers, microvolt scale. */
234 const int64_t avcc_uv = (int64_t)k_ra8_tsn_adc_avcc_uv;
235 const int64_t full_scale = (int64_t)k_ra8_tsn_adc_full_scale;
236 const int64_t v1_uv = (avcc_uv * (int64_t)cal_hi) / full_scale;
237 const int64_t v2_uv = (avcc_uv * (int64_t)cal_lo) / full_scale;
238 const int64_t vs_uv = (avcc_uv * (int64_t)raw_code) / full_scale;
239 const int64_t t1_milli_c = (int64_t)s_ra8_tsn_high_ref_degc * (int64_t)k_ra8_tsn_uv_per_mv;
240 const int64_t t2_milli_c = (int64_t)s_ra8_tsn_low_ref_degc * (int64_t)k_ra8_tsn_uv_per_mv;
241 const int64_t v_delta_uv = v1_uv - v2_uv; /* != 0 by guard above */
242 const int64_t numerator_uv = (vs_uv - v1_uv) * (t1_milli_c - t2_milli_c);
243 const int64_t result_milli = (numerator_uv / v_delta_uv) + t1_milli_c;
244
245 *out_milli_c = (int32_t)result_milli;
246 return k_ra8_ok;
247}
248
250{
251 RA8_CHECK_NULL_PTR(out_milli_c, s_tag, "out_milli_c must not be nullptr");
254 }
255
256 /* Drive the ADC temperature-sensor channel (CNVCS = 0x64) and read the
257 * raw code back from its ADEXDR4 result register (HUM Ch 53.2.13.2
258 * p 3391). The ADC side lives entirely in adc.c. */
259 uint16_t adc_raw = 0U;
261 /* GCOVR_EXCL_BR_START -- HW ADC read path */
262 RA8_RETURN_ON_ERROR(adc_err, s_tag, "die_temp: adc read");
263 /* GCOVR_EXCL_BR_STOP */
264
265 uint16_t code = 0U;
266 const ra8_err_t mask_err = ra8_tsn_read_raw(adc_raw, &code);
267 /* GCOVR_EXCL_BR_START -- HW ADC raw path */
268 RA8_RETURN_ON_ERROR(mask_err, s_tag, "die_temp: read_raw");
269 /* GCOVR_EXCL_BR_STOP */
270
271 return ra8_tsn_convert_to_milli_c(code, out_milli_c);
272}
273
275{
276 RA8_CHECK_NULL_PTR(out_tscr, s_tag, "out_tscr must not be nullptr");
277 /* HUM Ch 55.2.1 "TSCR : Temperature Sensor Control Register", p 3498 */
278 volatile const r_tsn_ctrl_regs_t* reg = ra8_tsn();
279 *out_tscr = (uint8_t)(reg->TSCR & k_ra8_tscr_mask_all);
280 return k_ra8_ok;
281}
282
284{
285 /* HUM Ch 55.2.1 "TSCR : Temperature Sensor Control Register", p 3498 */
286 volatile r_tsn_ctrl_regs_t* reg = ra8_tsn();
287 reg->TSCR = 0U;
288 return k_ra8_ok;
289}
290
292{
293 /* HUM Ch 11.2.9 "MSTPCRD : Module Stop Control Register D", p 449 */
295}
296
298{
299 /* HUM Ch 11.2.9 "MSTPCRD : Module Stop Control Register D", p 449 */
301}
Full-featured ADC_B driver.
ra8_err_t ra8_adc_read_internal_channel(ra8_adc_internal_chan_t chan, uint16_t *out_raw)
Blocking single conversion of an internal / extended-analog channel.
@ k_ra8_adc_chan_temperature
On-chip die-temperature sensor.
Definition ra8_adc.h:536
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
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
Shared CPU-intrinsic seam for the HAL drivers (host/target split).
static void ra8_hw_nop(void)
No-operation used to pad a calibrated busy-wait.
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_info(tag, message)
RA8 log info.
Definition ra8_log.h:364
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
ra8_err_t ra8_mstp_disable(ra8_mstp_t id)
Reference-counted "gate this peripheral" request.
Definition ra8_mstp.c:382
@ k_ra8_mstp_tsn
MSTPD22 Temperature.
ra8_err_t ra8_tsn_convert_to_milli_c(uint16_t raw_code, int32_t *out_milli_c)
Convert a raw 12-bit TSN code to milli-degrees-Celsius.
Definition ra8_tsn.c:214
ra8_err_t ra8_tsn_init(const ra8_tsn_config_t *cfg)
Power on the TSN block and enable its ADC output path.
Definition ra8_tsn.c:149
static ra8_err_t internal_validate_cfg(const ra8_tsn_config_t *cfg)
Validate the high/low reference temperatures in a config.
Definition ra8_tsn.c:129
static void internal_busy_wait_us(uint16_t usec)
Coarse software busy-wait used during init.
Definition ra8_tsn.c:101
ra8_err_t ra8_tsn_exit_stop(void)
Clear MSTPD22 to re-power the TSN block.
Definition ra8_tsn.c:297
ra8_err_t ra8_tsn_get_status(uint8_t *out_tscr)
Read TSCR (TSEN + TSOE bits).
Definition ra8_tsn.c:274
static int16_t s_ra8_tsn_high_ref_degc
Cached high-side calibration temperature.
Definition ra8_tsn.c:67
ra8_tsn_internal_t
Driver-internal magic values.
Definition ra8_tsn.c:45
@ k_ra8_tsn_min_stab_us
tTSTBL spec floor.
Definition ra8_tsn.c:46
@ k_ra8_tsn_busy_loops_per_us
Conservative spin count.
Definition ra8_tsn.c:47
ra8_err_t ra8_tsn_read_die_temp_milli_c(int32_t *out_milli_c)
Read the die temperature end-to-end through the HAL.
Definition ra8_tsn.c:249
ra8_err_t ra8_tsn_clear_status(void)
Clear TSCR (drive both TSEN and TSOE low).
Definition ra8_tsn.c:283
ra8_err_t ra8_tsn_read_raw(uint16_t raw, uint16_t *out_code)
Pass through a raw ADC sample of the TSN channel.
Definition ra8_tsn.c:202
static bool s_ra8_tsn_initialized
Tracks whether ra8_tsn_init has run successfully.
Definition ra8_tsn.c:57
ra8_err_t ra8_tsn_enter_stop(void)
Re-assert MSTPD22 to clock-gate the TSN block.
Definition ra8_tsn.c:291
static int16_t s_ra8_tsn_low_ref_degc
Cached low-side calibration temperature (always -40).
Definition ra8_tsn.c:73
ra8_err_t ra8_tsn_deinit(void)
Tear down the TSN block.
Definition ra8_tsn.c:180
On-chip Temperature Sensor (TSN) driver.
@ k_ra8_tsn_cal_temp_high_125
125 degC Tj_max parts.
Definition ra8_tsn.h:99
@ k_ra8_tsn_cal_temp_low_n40
Always -40 degC on RA8D2.
Definition ra8_tsn.h:101
@ k_ra8_tsn_cal_temp_high_105
95 / 105 degC parts.
Definition ra8_tsn.h:100
Temperature Sensor (TSN) register layout for the Renesas RA8D2.
@ k_ra8_tscdr_data_mask
12-bit data mask (HUM Ch 55.2.2 p 3498).
@ k_ra8_tscr_mask_tsoe
TSOE bit (ADC output enable).
@ k_ra8_tscr_mask_all
TSEN | TSOE.
@ k_ra8_tscr_mask_tsen
TSEN bit (sensor enable).
@ k_ra8_tsn_uv_per_mv
1000-x scale (degC -> mC).
@ k_ra8_tsn_adc_avcc_uv
AVCC = 3.3 V expressed in uV.
@ k_ra8_tsn_adc_full_scale
12-bit ADC full-scale.
static volatile r_tsn_ctrl_regs_t * ra8_tsn(void)
Get pointer to the TSN control block (HUM Ch 55.2.1 p 3498).
static volatile const r_tsn_cal_regs_t * ra8_tsn_cal(void)
Get pointer to the factory-calibration block (TSCDR + TSCDR2).
TSN factory-calibration block (read-only on hardware).
volatile uint32_t TSCDR2
+0x04 Calibration code at low ref temperature.
volatile uint32_t TSCDR
+0x00 Calibration code at high ref temperature.
TSN control block register window.
volatile uint8_t TSCR
+0x00 Temperature Sensor Control Register.
Configuration descriptor for ra8_tsn_init.
Definition ra8_tsn.h:121
uint16_t stab_us
tTSTBL in microseconds.
Definition ra8_tsn.h:124
ra8_tsn_cal_temp_t low_ref_degc
Always -40 degC on RA8D2.
Definition ra8_tsn.h:123
ra8_tsn_cal_temp_t high_ref_degc
105 or 125 degC.
Definition ra8_tsn.h:122