@@ -126,6 +126,16 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME));
126126#endif
127127#endif
128128
129+ #define INSTANCE_IS_HIGH_SPEED (unused , prefix , idx , _ ) \
130+ COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(UARTE(prefix##idx)), \
131+ ((NRF_PERIPH_GET_FREQUENCY(UARTE(prefix##idx)) > NRF_UARTE_BASE_FREQUENCY_16MHZ)), \
132+ (0))
133+
134+ /* Macro determines if there is any high speed instance (instance that is driven using
135+ * clock that is faster than 16 MHz).
136+ */
137+ #define UARTE_ANY_HIGH_SPEED (UARTE_FOR_EACH_INSTANCE(INSTANCE_IS_HIGH_SPEED, (||), (0)))
138+
129139#ifdef UARTE_ANY_CACHE
130140/* uart120 instance does not retain BAUDRATE register when ENABLE=0. When this instance
131141 * is used then baudrate must be set after enabling the peripheral and not before.
@@ -256,6 +266,17 @@ struct uarte_nrfx_data {
256266/* If enabled then UARTE peripheral is using memory which is cacheable. */
257267#define UARTE_CFG_FLAG_CACHEABLE BIT(3)
258268
269+ /* Formula for getting the baudrate settings is following:
270+ * 2^12 * (2^20 / (f_PCLK / desired_baudrate)) where f_PCLK is a frequency that
271+ * drives the UARTE.
272+ *
273+ * @param f_pclk Frequency of the clock that drives the peripheral.
274+ * @param baudrate Desired baudrate.
275+ *
276+ * @return Baudrate setting to be written to the BAUDRATE register
277+ */
278+ #define UARTE_GET_CUSTOM_BAUDRATE (f_pclk , baudrate ) ((BIT(20) / (f_pclk / baudrate)) << 12)
279+
259280/* Macro for converting numerical baudrate to register value. It is convenient
260281 * to use this approach because for constant input it can calculate nrf setting
261282 * at compile time.
@@ -495,18 +516,19 @@ static void uarte_nrfx_isr_int(const void *arg)
495516static int baudrate_set (const struct device * dev , uint32_t baudrate )
496517{
497518 const struct uarte_nrfx_config * config = dev -> config ;
519+ nrf_uarte_baudrate_t nrf_baudrate ;
520+
498521 /* calculated baudrate divisor */
499- nrf_uarte_baudrate_t nrf_baudrate = NRF_BAUDRATE (baudrate );
522+ if (UARTE_ANY_HIGH_SPEED && (config -> clock_freq > NRF_UARTE_BASE_FREQUENCY_16MHZ )) {
523+ nrf_baudrate = UARTE_GET_CUSTOM_BAUDRATE (config -> clock_freq , baudrate );
524+ } else {
525+ nrf_baudrate = NRF_BAUDRATE (baudrate );
526+ }
500527
501528 if (nrf_baudrate == 0 ) {
502529 return - EINVAL ;
503530 }
504531
505- /* scale baudrate setting */
506- if (config -> clock_freq > 0U ) {
507- nrf_baudrate /= config -> clock_freq / NRF_UARTE_BASE_FREQUENCY_16MHZ ;
508- }
509-
510532#ifdef UARTE_BAUDRATE_RETENTION_WORKAROUND
511533 struct uarte_nrfx_data * data = dev -> data ;
512534
@@ -2413,17 +2435,21 @@ static int uarte_instance_init(const struct device *dev,
24132435#define UARTE_DISABLE_RX_INIT (node_id ) \
24142436 .disable_rx = DT_PROP(node_id, disable_rx)
24152437
2416- /* Get frequency of the clock that driver the UARTE peripheral. Clock node can
2417- * have fixed or variable frequency. For fast UARTE use highest supported frequency.
2418- */
2419- #define UARTE_GET_BAUDRATE_DIV (idx ) \
2420- (NRF_PERIPH_GET_FREQUENCY(UARTE(idx)) / NRF_UARTE_BASE_FREQUENCY_16MHZ)
2438+ /* Get frequency divider that is used to adjust the BAUDRATE value. */
2439+ #define UARTE_GET_BAUDRATE_DIV (f_pclk ) (f_pclk / NRF_UARTE_BASE_FREQUENCY_16MHZ)
24212440
24222441/* When calculating baudrate we need to take into account that high speed instances
24232442 * must have baudrate adjust to the ratio between UARTE clocking frequency and 16 MHz.
2443+ * Additionally, >1Mbaud speeds are calculated using a formula.
24242444 */
2445+ #define UARTE_GET_BAUDRATE2 (f_pclk , current_speed ) \
2446+ ((f_pclk > NRF_UARTE_BASE_FREQUENCY_16MHZ) && (current_speed > 1000000)) ? \
2447+ UARTE_GET_CUSTOM_BAUDRATE(f_pclk, current_speed) : \
2448+ (NRF_BAUDRATE(current_speed) / UARTE_GET_BAUDRATE_DIV(f_pclk))
2449+
2450+ /* Convert DT current-speed to a value that is written to the BAUDRATE register. */
24252451#define UARTE_GET_BAUDRATE (idx ) \
2426- (NRF_BAUDRATE(UARTE_PROP (idx, current_speed)) / UARTE_GET_BAUDRATE_DIV (idx))
2452+ UARTE_GET_BAUDRATE2(NRF_PERIPH_GET_FREQUENCY(UARTE (idx)), UARTE_PROP (idx, current_speed ))
24272453
24282454/* Get initialization level of an instance. Instances that requires clock control
24292455 * which is using nrfs (IPC) are initialized later.
@@ -2488,12 +2514,11 @@ static int uarte_instance_init(const struct device *dev,
24882514 (.int_driven = &uarte##idx##_int_driven,)) \
24892515 }; \
24902516 COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE, (), \
2491- (BUILD_ASSERT(NRF_BAUDRATE(UARTE_PROP( idx, current_speed)) > 0,\
2492- "Unsupported baudrate");)) \
2517+ (BUILD_ASSERT(UARTE_GET_BAUDRATE( idx) > 0, \
2518+ "Unsupported baudrate");)) \
24932519 static const struct uarte_nrfx_config uarte_##idx##z_config = { \
24942520 COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE, \
2495- (IF_ENABLED(DT_CLOCKS_HAS_IDX(UARTE(idx), 0), \
2496- (.clock_freq = NRF_PERIPH_GET_FREQUENCY(UARTE(idx)),))), \
2521+ (.clock_freq = NRF_PERIPH_GET_FREQUENCY(UARTE(idx)),), \
24972522 (IF_ENABLED(UARTE_HAS_FRAME_TIMEOUT, \
24982523 (.baudrate = UARTE_PROP(idx, current_speed),)) \
24992524 .nrf_baudrate = UARTE_GET_BAUDRATE(idx), \
0 commit comments