UART(E): Add peripherals and connect to (D)PPI

Add the UART and UART-E perihperals
for the nrf52833 and 5340,
connecting them to the PPI/DPPI, int contrl.
and provide the necessary HAL replacements.

For these UARTs include a backend which allows
connecting 2 UARTs together thru named pipes.

Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
This commit is contained in:
Alberto Escolar Piedras 2023-12-06 17:18:50 +01:00
parent 9b985ea6bc
commit 6902527e27
21 changed files with 3227 additions and 20 deletions

View File

@ -53,7 +53,7 @@ Notation:
| **TEMP** | Temperature sensor | &#x2714; | &#x2714; | See [NHW_TEMP.c](../src/HW_models/NHW_TEMP.c) |
| **TIMER** | Timer/counter | &#x2705; | &#x2705; | |
| **TWI[M/S]** | I2C compatible two-wire interface | &#x10102; | &#x10102; | |
| **UART[E]** | Universal asynchronous receiver/transmitter [with EasyDMA] | &#x10102; | &#x10102; | |
| **UART[E]** | Universal asynchronous receiver/transmitter [with EasyDMA] | &#x2714; | &#x2714; | For 53: It cannot be used yet w Zephyr as the Zephyr driver requires a working nRF53 GPIO |
| **UICR** | User information configuration registers | &#x2714; | &#x2714; | See [NHW_NVMC.c](../src/HW_models/NHW_NVMC.c) |
| **USBD** | Universal serial bus device | &#x10102; | &#x10102; | |
| **USBREG** | Universal serial bus device | N/A | &#x10102; | |

83
docs/UART.md Normal file
View File

@ -0,0 +1,83 @@
## UART(E) models
A model of the UART and UART-E peripherals is included with these models.
You can find information about their limitations and approximations in
[the source files](../src/HW_models/NRF_UART.c).
The UART models are divided in 2 parts:
* A peripheral model, which emulates a nRF UART(E).
* A backend which can send and receive the data somewhere.
When using the peripheral you select which backend is used for each UART instance
with command line parameters.
If no backend is enabled, that UART instance is disconnected: whatever is sent is dropped, and
nothing is received.
### Logging to files
Each UART can be configured to log to a file the Tx and/or Rx bytes.
Enabling this and selecting the file is done with command line options.
When enabled, the model will dump one line in this file per byte, with two columns:
The first column is a timestamp, in microseconds, when the frame *ended*.
The second column is the byte itself.
### Test API
The UART also has a test API which allows embedded code to register callbacks to be
called whenever a byte is transmitted or received. This callback can replace the byte before
the UART peripheral processes it further. Check
[the UART header file](../src/HW_models/NRF_UART.h) for more info.
It is also possible for test code to call `nhw_UARTE_digest_Rx_byte()` to inject
bytes into the UART peripheral like if they arrived thru the Rx line.
### Backends:
Today there is only 1 backend to choose from:
* The FIFO backend.
#### The FIFO backend
This backend can connect two instances of these UART models to each other.
For this it uses one Linux FIFO (named pipe) for Tx and another for Rx.
In these pipes it will carry both the data, information about the CTS/RTS pin toggles,
bit rate, frame configuration, and other control messages.
Therefore you cannot connect this backend to a console, or real devices.
You enable this backend for each instance using command line parameters, by specifying
the path to each FIFO.
The backend will automatically create and delete the FIFOs on its own.
Remember to use unique paths for each simulation you run in parallel.
The backend will also realize about a possible abrupt disconnect from the other side.
In that case, it will terminate the simulation.
In case of a graceful disconnect from the other side, the backend will, by default, also
terminate the simulation; But you can change this with a command line option, so that it will
just disconnect the backend and continue running.
For performance reasons, the backend does not react immediately to a CTS/RTS pin toggle from the
other side. Instead up to 1 frame time (1 byte time) will elapse between the pin toggle
and the UART peripheral model being notified. Note that the UART peripheral has a 6 byte Rx FIFO,
and that it toggles RTS while there is still 4 spaces left. So even though this will, in some cases,
cause up to 1 extra byte to be send to the other side, it should not cause any transmission losses.
If there is a miss-configuration between the devices (bit rate, parity or number of stop bits),
the backend will print a warning for each received byte, but the ERRORSRC register in the UART
peripheral won't be set due to fame, or parity errors, or break conditions.
#### Loopback
It is possible to connect a UART instance Tx directly to its Rx (or to another instance Rx),
and have the RTR will be propagated to the CTS.
To do this, just configure the same FIFO file name for both the Rx and Tx, for example like:
`-uart0_fifob_rxfile=looped_back -uart0_fifob_txfile=looped_back`
**IMPOTANT**:
Do not connect both devices which are connected thru the UART to the Physical layer
simulation. Connect only the one which has the controller.
Otherwise, with the current implementation the simulation will deadlock with very high
likelihood, and if it does not deadlock it will slow down the simulation considerably.
You can still provide the sim_id and an unused device number to the other device, but
in that case, launch it with the `-nosim` option.

View File

@ -14,3 +14,5 @@ src/nrfx/hal/nrf_rng.c
src/nrfx/hal/nrf_aar.c
src/nrfx/hal/nrf_ppi.c
src/nrfx/hal/nrf_ecb.c
src/nrfx/hal/nrf_uart.c
src/nrfx/hal/nrf_uarte.c

View File

@ -23,6 +23,8 @@ src/HW_models/bstest_ticker.c
src/HW_models/NRF_GPIO.c
src/HW_models/NHW_TEMP.c
src/HW_models/NHW_TIMER.c
src/HW_models/NHW_UART.c
src/HW_models/NHW_UART_backend_fifo.c
src/HW_models/bs_compat.c
src/HW_models/NHW_52_FICR.c
src/HW_models/NRF_GPIOTE.c

View File

@ -9,3 +9,4 @@ src/nrfx/hal/nrf_nvmc.c
src/nrfx/hal/nrf_rtc.c
src/nrfx/hal/nrf_timer.c
src/nrfx/hal/nrf_hal_originals.c
src/nrfx/hal/nrf_uarte.c

View File

@ -28,5 +28,7 @@ src/HW_models/NHW_RTC.c
src/HW_models/NHW_SWI.c
src/HW_models/NHW_TIMER.c
src/HW_models/NHW_TEMP.c
src/HW_models/NHW_UART.c
src/HW_models/NHW_UART_backend_fifo.c
src/HW_models/NHW_VREQCTRL.c
src/HW_models/weak_stubs.c

View File

@ -15,3 +15,4 @@ src/nrfx/hal/nrf_rtc.c
src/nrfx/hal/nrf_temp.c
src/nrfx/hal/nrf_timer.c
src/nrfx/hal/nrf_hal_originals.c
src/nrfx/hal/nrf_uarte.c

1116
src/HW_models/NHW_UART.c Normal file

File diff suppressed because it is too large Load Diff

91
src/HW_models/NHW_UART.h Normal file
View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _NRF_HW_MODEL_UART_H
#define _NRF_HW_MODEL_UART_H
#include "bs_types.h"
#include <stdint.h>
#include "NHW_config.h"
#ifdef __cplusplus
extern "C"{
#endif
void nhw_UARTE_regw_sideeffects_TASKS_STARTRX(uint i);
void nhw_UARTE_regw_sideeffects_TASKS_STOPRX(uint i);
void nhw_UARTE_regw_sideeffects_TASKS_STARTTX(uint i);
void nhw_UARTE_regw_sideeffects_TASKS_STOPTX(uint i);
void nhw_UARTE_regw_sideeffects_TASKS_SUSPEND(uint i);
void nhw_UARTE_regw_sideeffects_TASKS_FLUSHRX(uint i);
void nhw_UARTE_regw_sideeffects_INTENSET(uint i);
void nhw_UARTE_regw_sideeffects_INTENCLR(uint i);
/* Side-effecting function when any event register is written: */
void nhw_UARTE_regw_sideeffects_EVENTS_all(uint t);
void nhw_UARTE_regw_sideeffects_SUBSCRIBE_STARTRX(uint i);
void nhw_UARTE_regw_sideeffects_SUBSCRIBE_STOPRX(uint i);
void nhw_UARTE_regw_sideeffects_SUBSCRIBE_STARTTX(uint i);
void nhw_UARTE_regw_sideeffects_SUBSCRIBE_STOPTX(uint i);
void nhw_UARTE_regw_sideeffects_SUBSCRIBE_FLUSHRX(uint i);
uint32_t nhw_UARTE_regr_sideeffects_ERRORSRC(unsigned int inst);
void nhw_UARTE_regw_sideeffects_ERRORSRC(unsigned int inst);
uint32_t nhw_UARTE_regr_sideeffects_RXD(unsigned int inst);
void nhw_UARTE_regw_sideeffects_TXD(unsigned int inst);
void nhw_UARTE_regw_sideeffects_ENABLE(unsigned int inst);
#if (NHW_HAS_PPI)
void nhw_uarte0_TASKS_STARTRX(void);
void nhw_uarte0_TASKS_STOPRX(void);
void nhw_uarte0_TASKS_STARTTX(void);
void nhw_uarte0_TASKS_STOPTX(void);
void nhw_uarte0_TASKS_SUSPEND(void);
void nhw_uarte0_TASKS_FLUSHRX(void);
void nhw_uarte1_TASKS_STARTRX(void);
void nhw_uarte1_TASKS_STOPRX(void);
void nhw_uarte1_TASKS_STARTTX(void);
void nhw_uarte1_TASKS_STOPTX(void);
void nhw_uarte1_TASKS_SUSPEND(void);
void nhw_uarte1_TASKS_FLUSHRX(void);
#endif /* (NHW_HAS_PPI) */
extern NRF_UARTE_Type NRF_UARTE_regs[];
#if (NHW_UARTE_HAS_UART)
extern NRF_UART_Type *NRF_UART_regs[];
#endif
typedef void (*uart_rtxb_cb_f)(uint inst, uint8_t *data);
/*
* (Test interface) Register a callback which will be called
* each time a byte is transmitted or received.
* The callback may replace that byte with something else which will
* be {stored in the UART Rx FIFO, sent over the line} instead of
* the original byte.
*
* If the callback does not want to modify the data being received,
* it should not modify the content of *data.
*
* This function returns the pointer to a possible previously registered
* {Rx,Tx} callback (NULL if none was registered)
*
* <inst> is the UART instance for which we are registering the callback.
* UARTs are indexed globally for the whole SOC, as shown in NHW_config.h
* and --uart_list
* <Rx_NotTx> should be set 1 to set the Rx callback, 0 to set the Tx callback
*/
uart_rtxb_cb_f nhw_uarte_register_callback(int inst, uart_rtxb_cb_f cb, bool Rx_NotTx);
#ifdef __cplusplus
}
#endif
#endif /* _NRF_HW_MODEL_UART_H */

View File

@ -0,0 +1,683 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Backend for the UART(E) which connects to a compatible backend on another device.
*
* It accounts for the RTS|R/CTS flow control, and byte timing.
*
* Mismatches in the UART configuration and baudrate, only result in a warning
* but the data is accepted without generating error events.
*
* When selected it *requires* the other end to be connected as soon as the UART HW is enabled.
*
* Notes:
* * This backend is heavy/slow, it is very strongly recommended to NOT use it
* in 2 devices which are also connected thru the Phy.
* It is also discouraged to use it for anything beyond testing of UART related code.
*
* * The protocol this backend uses does not follow any standard, and it is not
* an API with any stability promise, if you connect your own UART model to its FIFO
* you should expect that to break eventually.
*
* * When both Tx and Rx are off, CTS toggles will not generate the events in the right
* time but those events will be generated in bursts (as we are not monitoring constantly the input)
* Therefore for the UART(not E), a toggle of CTS will not trigger the StartRx/StopRx
* shortcuts in the right time.
*/
#include <stdint.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <math.h>
#include "bs_types.h"
#include "bs_tracing.h"
#include "bs_oswrap.h"
#include "bs_compat.h"
#include "bs_utils.h"
#include "bs_cmd_line.h"
#include "bs_dynargs.h"
#include "bs_pc_base_fifo_user.h"
#include "NHW_config.h"
#include "NHW_peri_types.h"
#include "NHW_UART_backend_if.h"
#include "NHW_UART_backend_fifo.h"
#include "nsi_hw_scheduler.h"
#include "nsi_tasks.h"
#include "nsi_hws_models_if.h"
static bs_time_t Timer_UFIFO = TIME_NEVER;
/* Factor for the fastest reaction time to propagate an event to the other side
* relative to a frame (byte transfer time) size.
* This reaction time is frame_time / TX_MIN_DELTA_RATIO.
* (Note the smallest byte time is 10 micros at 1Mbps no parity and 1 stop bit,
* so for TX_MIN_DELTA_RATIO = 2 that is 5 micros )
* The higher this value, the more accurate the flow control timing will be.
* Byte timing will always be fully accurate.
* But the higher this value the higher the processing overhead.
*/
#define TX_MIN_DELTA_RATIO 1
struct line_params {
uint32_t config;
uint32_t baud;
};
struct ufifo_st_t {
bs_time_t Rx_timer;
bs_time_t Tx_timer;
char *fifo_Tx_path;
char *fifo_Rx_path;
int fifo_tx; /* File descriptor for tx */
int fifo_rx; /* File descriptor for rx */
bool enabled; /* Has it been chosen for this instance in the command line (and not yet disconnected) */
bool tx_on;
bool rx_on;
bool rx_low_dutyc_mode;
bool disconnected;
struct line_params tx_line_params;
char last_rx_msg[UFIFO_BIGGEST_MSG];
bool last_rx_msg_pending; /* The message in last_rx_msg is between pre and post processing (1)
or already processed (0) */
struct line_params rx_line_params;
bool cts; /* CTS signal we are getting from other device (starts high => not clear) */
char rx_byte;
};
struct ufifo_st_t ufifo_st[NHW_UARTE_TOTAL_INST];
static bool uf_dont_terminate_on_disconnect;
static double uf_mdt;
static void nhw_ufifo_update_timer(void);
static void nhw_ufifo_create_fifos(uint inst, struct ufifo_st_t *u_el);
static void nhw_ufifo_tx_byte(uint inst, uint8_t data);
static void nhw_ufifo_RTS_pin_toggle(uint inst, bool new_level);
static void nhw_ufifo_enable_notify(uint inst, uint8_t tx_enabled, uint8_t rx_enabled);
static void uf_Rx_handle_old_input(uint inst, struct ufifo_st_t *u_el);
static void nhw_ufifo_backend_init(void) {
/* Let's make sure we ignore broken pipe signals even if we are not connected to a Phy*/
signal(SIGPIPE, SIG_IGN);
for (int i = 0; i < NHW_UARTE_TOTAL_INST; i++) {
struct ufifo_st_t *u_el = &ufifo_st[i];
u_el->Rx_timer = TIME_NEVER;
u_el->Tx_timer = TIME_NEVER;
u_el->fifo_tx = -1;
u_el->fifo_rx = -1;
u_el->tx_line_params.config = UINT32_MAX;
u_el->tx_line_params.baud = UINT32_MAX;
u_el->rx_line_params.config = UINT32_MAX;
u_el->rx_line_params.baud = UINT32_MAX;
u_el->cts = true;
if (!u_el->enabled) {
continue;
}
nhw_ufifo_create_fifos(i, u_el);
struct backend_if st;
st.tx_byte_f = nhw_ufifo_tx_byte;
st.RTS_pin_toggle_f = nhw_ufifo_RTS_pin_toggle;
st.uart_enable_notify_f = nhw_ufifo_enable_notify;
nhw_UARTE_backend_register(i, &st);
u_el->Tx_timer = 0;
u_el->Rx_timer = uf_mdt;
u_el->rx_low_dutyc_mode = true;
}
nhw_ufifo_update_timer();
}
NSI_TASK(nhw_ufifo_backend_init, HW_INIT, 100); /* this must be before the uart itself */
static void write_to_tx_fifo(struct ufifo_st_t *u_el, void *ptr, size_t size) {
int res = write(u_el->fifo_tx, ptr, size);
if (res != size) {
u_el->disconnected = true;
if ((res == -1) && (errno == EPIPE)) {
/* The other side disconnected unexpectedly, let's terminate */
bs_trace_error_time_line("UART: Other end disconnected unexpectedly, terminating\n");
} else {
bs_trace_error_time_line("UART: Unexpected error while writing (%i, %i) (or interrupted). "
"Terminating\n", res, errno);
}
}
}
static void tx_set_next_tx_timer(uint inst, struct ufifo_st_t *u_el, bs_time_t last_act) {
u_el->Tx_timer = BS_MAX(last_act, u_el->Tx_timer);
nsi_hws_find_next_event();
}
static void tx_sync_line_params(uint inst, struct ufifo_st_t *u_el) {
u_el->tx_line_params.config = NRF_UARTE_regs[inst].CONFIG;
u_el->tx_line_params.baud = NRF_UARTE_regs[inst].BAUDRATE;
struct ufifo_msg_mode_change msg;
msg.header.time = nsi_hws_get_time();
msg.header.size = sizeof(msg);
msg.header.msg_type = ufifo_MODE_CHANGE;
msg.config = u_el->tx_line_params.config;
msg.baudrate = u_el->tx_line_params.baud;
write_to_tx_fifo(u_el, (void *)&msg, sizeof(msg));
tx_set_next_tx_timer(inst, u_el, msg.header.time);
}
static void tx_nop(uint inst, struct ufifo_st_t *u_el, bs_time_t t) {
struct ufifo_msg_header msg;
msg.time = t;
msg.size = sizeof(msg);
msg.msg_type = ufifo_NOP;
write_to_tx_fifo(u_el, (void *)&msg, sizeof(msg));
tx_set_next_tx_timer(inst, u_el, msg.time);
}
static void tx_disconnect(uint inst, struct ufifo_st_t *u_el) {
struct ufifo_msg_header msg;
msg.time = 0;
msg.size = sizeof(msg);
msg.msg_type = ufifo_DISCONNECT;
write_to_tx_fifo(u_el, (void *)&msg, sizeof(msg));
}
static void nhw_ufifo_tx_byte(uint inst, uint8_t data) {
struct ufifo_st_t *u_el = &ufifo_st[inst];
if (!u_el->enabled) {
bs_trace_error_time_line("Progamming error\n");
}
if ((NRF_UARTE_regs[inst].CONFIG != u_el->tx_line_params.config)
|| (NRF_UARTE_regs[inst].BAUDRATE != u_el->tx_line_params.baud)) {
tx_sync_line_params(inst, u_el);
}
struct ufifo_msg_tx msg;
msg.header.time = nsi_hws_get_time() + nhw_uarte_one_byte_time(inst);
msg.header.size = sizeof(msg);
msg.header.msg_type = ufifo_TX_BYTE;
msg.data = data;
write_to_tx_fifo(u_el, (void *)&msg, sizeof(msg));
tx_set_next_tx_timer(inst, u_el, msg.header.time);
}
static void nhw_ufifo_RTS_pin_toggle(uint inst, bool new_level) {
struct ufifo_st_t *u_el = &ufifo_st[inst];
if (!u_el->enabled) {
bs_trace_error_time_line("Progamming error\n");
}
struct ufifo_msg_rts_cts msg;
msg.header.time = nsi_hws_get_time();
msg.header.size = sizeof(msg);
msg.header.msg_type = ufifo_RTS_CTS_TOGGLE;
msg.level = new_level;
write_to_tx_fifo(u_el, (void *)&msg, sizeof(msg));
tx_set_next_tx_timer(inst, u_el, msg.header.time);
}
static void nhw_ufifo_enable_notify(uint inst, uint8_t tx_enabled, uint8_t rx_enabled) {
struct ufifo_st_t *u_el = &ufifo_st[inst];
if (!u_el->enabled) {
bs_trace_error_time_line("Progamming error\n");
}
u_el->tx_on = tx_enabled;
u_el->rx_on = rx_enabled;
if ((u_el->rx_low_dutyc_mode == true) &&
((tx_enabled == true) || (rx_enabled == true)) ) {
/* If we are in low duty cycle mode, let's get out of it right away */
u_el->Rx_timer = nsi_hws_get_time();
nhw_ufifo_update_timer();
}
}
static void nhw_ufifo_update_timer(void) {
Timer_UFIFO = TIME_NEVER;
for (int i = 0; i < NHW_UARTE_TOTAL_INST; i++) {
struct ufifo_st_t * u_el = &ufifo_st[i];
if (!u_el->enabled) {
continue;
}
bs_time_t smaller = BS_MIN(u_el->Rx_timer, u_el->Tx_timer);
Timer_UFIFO = BS_MIN(Timer_UFIFO, smaller);
}
nsi_hws_find_next_event();
}
static void uf_propage_cts(uint inst, struct ufifo_st_t *u_el) {
if (u_el->cts) {
nhw_UARTE_CTS_raised(inst);
} else {
nhw_UARTE_CTS_lowered(inst);
}
}
static int uf_rx_lowlevel_read(struct ufifo_st_t *u_el, void *buf, size_t size) {
int ret = read(u_el->fifo_rx, buf, size);
if (ret != size) {
u_el->disconnected = true;
if (ret == 0) {
bs_trace_error_time_line("UART: Other end disconnected unexpectedly\n");
} else {
bs_trace_error_time_line("UART: Read interrupted, or other unexpected error => terminating (%i, %s)\n",
ret, strerror(errno));
}
}
return ret;
}
/*
* Get one message from the Rx FIFO
* And for
* NOP: do nothing
* MODE_CHANGE: update u_el->rx_line_params
* TX_BYTE: copy byte to u_el->rx_byte
* RTS_CTS_TOGGLE: update u_el->cts
* DISCONNECT: Disconnect this FIFO instance (set timers in never, and disconnect from peripheral)
*
* returns message type
*/
static int uf_rx_get_one_msg(uint inst, struct ufifo_st_t *u_el) {
struct ufifo_msg_header *buf = (struct ufifo_msg_header *)u_el->last_rx_msg;
uf_rx_lowlevel_read(u_el, (void *)buf, UFIFO_MSG_HEADER_SIZE);
switch (buf->msg_type) {
case ufifo_MODE_CHANGE:
uf_rx_lowlevel_read(u_el, (char *)buf + UFIFO_MSG_HEADER_SIZE, UFIFO_MSG_MODE_CHANGE_BODY_SIZE);
u_el->rx_line_params.baud = ((struct ufifo_msg_mode_change *)buf)->baudrate;
u_el->rx_line_params.config = ((struct ufifo_msg_mode_change *)buf)->config;
break;
case ufifo_DISCONNECT:
u_el->disconnected = true;
if (!uf_dont_terminate_on_disconnect) {
bs_trace_exit_line_time("UART%i: Other end disconnected. Terminating\n", inst);
} else {
bs_trace_raw_time(3, "UART%i: Other end disconnected, UART%i backend disabled\n", inst, inst);
u_el->enabled = false;
u_el->Rx_timer = TIME_NEVER;
u_el->Tx_timer = TIME_NEVER;
nhw_ufifo_update_timer();
// Unregister from UART peri this instance so we never get another call:
struct backend_if st;
memset(&st, 0, sizeof(st));
nhw_UARTE_backend_register(inst, &st);
}
break;
case ufifo_TX_BYTE:
uf_rx_lowlevel_read(u_el, (char *)buf + UFIFO_MSG_HEADER_SIZE, UFIFO_MSG_TXL_BODY_SIZE);
u_el->rx_byte = ((struct ufifo_msg_tx *)buf)->data;;
break;
case ufifo_NOP:
break;
case ufifo_RTS_CTS_TOGGLE:
uf_rx_lowlevel_read(u_el, (char *)buf + UFIFO_MSG_HEADER_SIZE, UFIFO_MSG_RTS_CTS_BODY_SIZE);
u_el->cts = ((struct ufifo_msg_rts_cts *)buf)->level;
break;
default:
bs_trace_error_time_line("Corrupted stream\n");
break;
}
return buf->msg_type;
}
/*
* Process the last received msg
* (Which may result in a pended call to nhw_ufifo_handle_RxTimer() )
*/
static void uf_rx_process_last_msg_pre(uint inst, struct ufifo_st_t *u_el) {
struct ufifo_msg_header *buf = (struct ufifo_msg_header *)u_el->last_rx_msg;
switch (buf->msg_type) {
case ufifo_DISCONNECT:
return; /* Was already processed */
case ufifo_MODE_CHANGE:
case ufifo_NOP:
/* TOLOW: We can do a optimization here, by checking what is {ONT = the next schedueled event in the nsi hws}
* And if (ONT > buf->time) get another message from the Rx queue right away, as we anyhow would not do anything in the meanwhile
* (doing so would avoid possible abort reevaluations towards the phy, and loops thru the UART itself)
*/
case ufifo_TX_BYTE:
case ufifo_RTS_CTS_TOGGLE:
u_el->last_rx_msg_pending = true;
u_el->Rx_timer = BS_MAX(buf->time, nsi_hws_get_time());
nhw_ufifo_update_timer();
break;
default:
bs_trace_error_time_line("Programming error\n");
break;
}
}
static void uf_rx_check_config_match(uint inst, struct ufifo_st_t *u_el) {
if (( (NRF_UARTE_regs[inst].CONFIG & ~UART_CONFIG_HWFC_Msk)
!= (u_el->rx_line_params.config & ~UART_CONFIG_HWFC_Msk)
)
|| (NRF_UARTE_regs[inst].BAUDRATE != u_el->rx_line_params.baud)) {
bs_trace_warning_time_line("UART%i: Receiving a byte with mismatched configuration. "
"This would result in a line error in a real UART. Here you just get this warning "
"(UARTE_regs.CONFIG = %"PRIu32" !=? %"PRIu32 " in other side ;"
"(UARTE_regs.BAUDRATE = %"PRIu32" !=? %"PRIu32" in other side\n",
inst,
NRF_UARTE_regs[inst].CONFIG, u_el->rx_line_params.config,
NRF_UARTE_regs[inst].BAUDRATE, u_el->rx_line_params.baud
);
}
}
/*
* Finish processing the last received msg if needed (at the RxTimer time)
*/
static void uf_rx_process_last_msg_post(uint inst, struct ufifo_st_t *u_el) {
struct ufifo_msg_header *buf = (struct ufifo_msg_header *)u_el->last_rx_msg;
if (u_el->last_rx_msg_pending == false) {
return;
}
u_el->last_rx_msg_pending = false;
switch (buf->msg_type) {
case ufifo_NOP:
case ufifo_MODE_CHANGE:
/* Nothing left to be done */
break;
case ufifo_TX_BYTE:
if (u_el->rx_on) {
bs_trace_info_time(8, "UART%i: Received byte (0x%02X)\n",
inst, ((struct ufifo_msg_tx *)buf)->data);
uf_rx_check_config_match(inst, u_el);
nhw_UARTE_digest_Rx_byte(inst, u_el->rx_byte);
} else {
bs_trace_info_time(3, "UART%i: Received byte (0x%02X) while Rx was off => ignored\n",
inst, ((struct ufifo_msg_tx *)buf)->data);
}
break;
case ufifo_RTS_CTS_TOGGLE:
uf_propage_cts(inst, u_el);
break;
case ufifo_DISCONNECT:
/* We should not have reached this point */
default:
bs_trace_error_time_line("Programming error\n");
break;
}
}
/*
* Dequeue all old input in the Rx FIFO until now
*/
static void uf_Rx_handle_old_input(uint inst, struct ufifo_st_t *u_el) {
struct ufifo_msg_header *buf = (struct ufifo_msg_header *)u_el->last_rx_msg;
bs_time_t now = nsi_hws_get_time();
do {
uf_rx_get_one_msg(inst, u_el);
if (buf->time < now) {
switch (buf->msg_type) {
case ufifo_NOP: //We just ignore them while clearing
case ufifo_MODE_CHANGE:
break;
case ufifo_TX_BYTE:
if ((buf->time < now)) {
char byte = ((struct ufifo_msg_tx *)buf)->data;
bs_trace_info_time(3, "UART%i: Received byte (0x%02X) while Rx was off => ignored\n", inst, byte);
}
break;
case ufifo_RTS_CTS_TOGGLE:
/* We propagate past toggles right away to the UART */
uf_propage_cts(inst, u_el); //Note both Tx and Rx are disabled right now
break;
case ufifo_DISCONNECT:
return;
default:
bs_trace_error_time_line("Programming error\n");
break;
}
} else {
break;
}
} while (true);
//TOLOW: Check for Tx byte *started* in the past and disregard too (by setting header as NOP)
uf_rx_process_last_msg_pre(inst, u_el);
}
static void nhw_ufifo_handle_RxTimer(int inst, struct ufifo_st_t *u_el) {
if (u_el->rx_low_dutyc_mode) {
/*
* Low duty cycle:
* (1) We pick all old messages, and the first that points at now or the future
* And we schedule nhw_ufifo_handle_RxTimer() to parse that last one normally
* (we get out of low duty cycle mode, and maybe we get in again after)
*/
u_el->rx_low_dutyc_mode = false;
uf_Rx_handle_old_input(inst, u_el);
return;
}
uf_rx_process_last_msg_post(inst, u_el);
if (u_el->tx_on || u_el->rx_on) {
uf_rx_get_one_msg(inst, u_el);
uf_rx_process_last_msg_pre(inst, u_el);
} else {
/* Low duty cycle (2):
* If the Tx and Rx are off, we go into low duty cycle mode:
* Instead of picking the next Rx msg now, we postpone picking it for uf_mdt (10ms)
* => when we come back to nhw_ufifo_handle_RxTimer() thru (1)
*
* Low dutycycle mode may be sped up at any point by setting the Rx_timer to a earlier value
*/
u_el->rx_low_dutyc_mode = true;
u_el->Rx_timer = nsi_hws_get_time() + uf_mdt;
nhw_ufifo_update_timer();
}
}
static void nhw_ufifo_handle_TxTimer(int inst, struct ufifo_st_t *u_el) {
bs_time_t t;
u_el->Tx_timer = TIME_NEVER;
nsi_hws_find_next_event();
t = nsi_hws_get_next_event_time() + nhw_uarte_one_byte_time(inst)/TX_MIN_DELTA_RATIO;
u_el->Tx_timer = t;
tx_nop(inst, u_el, t);
}
static void nhw_ufifo_timer_triggered(void) {
bs_time_t current_time = Timer_UFIFO;
for (int i = 0; i < NHW_UARTE_TOTAL_INST; i++) {
struct ufifo_st_t *u_el = &ufifo_st[i];
if (u_el->Tx_timer == current_time) {
nhw_ufifo_handle_TxTimer(i, u_el);
}
if (u_el->Rx_timer == current_time) {
nhw_ufifo_handle_RxTimer(i, u_el);
}
}
nhw_ufifo_update_timer();
}
NSI_HW_EVENT(Timer_UFIFO, nhw_ufifo_timer_triggered, 900); /* Let's let as many timers as possible evaluate before this one */
static void uf_parse_mdt(char *argv, int offset) {
if (uf_mdt < 1 || uf_mdt > 1e6) {
bs_trace_error_line("uart_fifob_mdt must be set to a value between 1 and 1e6 (%s)\n", argv);
}
}
static void nhw_ufifo_backend_register_cmdline(void) {
static bs_args_struct_t args2[2*NHW_UARTE_TOTAL_INST + 1 /* End marker */];
static char descr_tx[] = "Path to the FIFO to be used for Tx (it will be created automatically). "
"Remember to cross them between devices. "
"Setting this option enables the FIFO backend for this UART";
static char descr_rx[] = "Path to the FIFO to be used for Rx (it will be created automatically)";
#define OPTION_LEN (4 + 2 + 13 + 1)
static char options[NHW_UARTE_TOTAL_INST][2][OPTION_LEN];
static char opt_name[]= "path";
for (int i = 0 ; i < NHW_UARTE_TOTAL_INST; i++) {
snprintf(options[i][0], OPTION_LEN, "uart%i_fifob_txfile", i);
snprintf(options[i][1], OPTION_LEN, "uart%i_fifob_rxfile", i);
args2[2*i].option = options[i][0];
args2[2*i].name = opt_name;
args2[2*i].type = 's';
args2[2*i].dest = &ufifo_st[i].fifo_Tx_path;
args2[2*i].descript = descr_tx;
args2[2*i + 1].option = options[i][1];
args2[2*i + 1].name = opt_name;
args2[2*i + 1].type = 's';
args2[2*i + 1].dest = &ufifo_st[i].fifo_Rx_path;
args2[2*i + 1].descript = descr_rx;
}
bs_add_extra_dynargs(args2);
static bs_args_struct_t args1[] = {
{ .is_switch = true,
.option = "uart_fifob_no_terminate",
.type = 'b',
.dest = (void *)&uf_dont_terminate_on_disconnect,
.descript = "Do NOT terminate execution of this device when the other end disconnects "
"gracefully"
},
{ .option = "uart_fifob_mdt",
.type = 'd',
.call_when_found = uf_parse_mdt,
.dest = (void *)&uf_mdt,
.descript = "(By default 10e3=10ms) Maximum amount of time the backend will spend without dequeuing"
"the Rx FIFO when the UART is not running in Tx or Rx mode. "
"This needs to be small enough to avoid the pipe from filling up and causing"
"a deadlock. It can also be set to a very small value (order of 10micros) if you want to"
"ensure the UART keeps registering the CTS signal toggles even when it is not running"
"(This only makes sense if you have registered a short or a PPI event in the CTS signal"
"events). The smaller the value the greater the overhead."
},
ARG_TABLE_ENDMARKER
};
bs_add_extra_dynargs(args1);
}
NSI_TASK(nhw_ufifo_backend_register_cmdline, PRE_BOOT_1, 200);
static void nhw_ufifo_backend_post_cmdline(void) {
for (int i = 0; i < NHW_UARTE_TOTAL_INST; i++) {
struct ufifo_st_t *u_el = &ufifo_st[i];
if ((u_el->fifo_Rx_path == NULL) && (u_el->fifo_Rx_path == NULL)) {
continue;
}
if (u_el->fifo_Tx_path == NULL) {
bs_trace_error_line("UART%i: uart_fifob_rxfile was provided but not uart_fifob_txfile. "
"If you want to use the FIFO backend you must provide both\n",i);
}
if (u_el->fifo_Rx_path == NULL) {
bs_trace_error_line("UART%i: uart_fifob_txfile was provided but not uart_fifob_rxfile. "
"If you want to use the FIFO backend you must provide both\n",i);
}
u_el->enabled = true;
}
if (isnan(uf_mdt)) {
uf_mdt = 10000;
}
}
NSI_TASK(nhw_ufifo_backend_post_cmdline, PRE_BOOT_2, 200);
/*
* Create FIFOs towards the other device and open both from our end.
* But do not block. The Tx FIFO is as nonblocking, and the Rx
* FIFO is reconfigured as blocking.
*/
static void nhw_ufifo_create_fifos(uint inst, struct ufifo_st_t *u_el) {
bs_trace_raw_time(9, "Creating UART%i backend FIFOs, and connecting Tx end\n", inst);
_bs_create_folders_in_path(u_el->fifo_Tx_path);
_bs_create_folders_in_path(u_el->fifo_Rx_path);
if (pb_create_fifo_if_not_there(u_el->fifo_Tx_path) != 0) {
bs_trace_error_line("Couldn't create UART backend Tx FIFOs\n");
}
if (pb_create_fifo_if_not_there(u_el->fifo_Rx_path) != 0) {
bs_trace_error_line("Couldn't create UART backend Rx FIFOs\n");
}
u_el->fifo_rx = open(u_el->fifo_Rx_path, O_RDONLY | O_NONBLOCK);
if (u_el->fifo_rx == -1) {
bs_trace_error_line("Couldn't open UART backend Rx FIFOs\n");
}
/* We clear NONBLOCK so the reads block until data is ready */
int flags = fcntl(u_el->fifo_rx, F_GETFL);
flags ^= O_NONBLOCK;
fcntl(u_el->fifo_rx, F_SETFL, flags);
/* We block here until the other side is connected */
u_el->fifo_tx = open(u_el->fifo_Tx_path, O_WRONLY);
if (u_el->fifo_tx == -1) {
bs_trace_error_line("Couldn't open UART backend Tx FIFOs\n");
}
}
static void nhw_ufifo_backend_cleanup(void) {
bs_trace_raw_time(9, "Cleaning up UART backend FIFOs\n");
for (int i = 0; i < NHW_UARTE_TOTAL_INST; i++) {
struct ufifo_st_t *u_el = &ufifo_st[i];
if ((u_el->fifo_Tx_path) && (u_el->fifo_tx != -1)) {
if (!u_el->disconnected) {
tx_disconnect(i, u_el);
}
close(u_el->fifo_tx);
u_el->fifo_tx = -1;
remove(u_el->fifo_Tx_path); /* The last one closing manages to remove it (so we don't check for success) */
u_el->fifo_Tx_path = NULL;
}
if ((u_el->fifo_Rx_path) && (u_el->fifo_rx != -1)) {
close(u_el->fifo_rx);
u_el->fifo_rx = -1;
remove(u_el->fifo_Rx_path); /* The last one closing manages to remove it (so we don't check for success) */
u_el->fifo_Rx_path = NULL;
}
}
}
NSI_TASK(nhw_ufifo_backend_cleanup, ON_EXIT_PRE, 100);

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _NRF_HW_MODEL_BACKEND_FIFO_H
#define _NRF_HW_MODEL_BACKEND_FIFO_H
#include <stdint.h>
#include "bs_types.h"
#ifdef __cplusplus
extern "C"{
#endif
/*
* Protocol
*
* The device creates (if not there) and opens its Tx side FIFO at boot
* The device tries to opens its Rx side FIFO when the UART is enabled first time
*
* Messages:
* <uint64_t time> <uint8_t msg_type> <uint16_t msg_size (including time and msg_type)>
* <...>
*
* <uint64_t time> MODE_CHANGE <msg_size>
* <uint32_t baudrate> <uint32_t config>
* (note the time stamp is ignored, as only the next Tx is affected by the rate change)
*
* <uint64_t time> TX_BYTE <msg_size>
* <uint8_t data >
* (note time is when the frame ends)
*
* <uint64_t time> RTS_CTS_TOGGLE <msg_size>
* <uint8_t level {0,1}>
*
* <uint64_t time> NOP <msg_size>
*
* <uint64_t time> DISCONNECT <msg_size>
* The other side is disconnecting gracefully
*/
struct ufifo_msg_header {
bs_time_t time;
enum {ufifo_NOP=0, ufifo_MODE_CHANGE, ufifo_TX_BYTE, ufifo_RTS_CTS_TOGGLE, ufifo_DISCONNECT} msg_type;
uint16_t size;
} __attribute__ ((packed));
struct ufifo_msg_tx {
struct ufifo_msg_header header;
uint8_t data;
} __attribute__ ((packed));
struct ufifo_msg_rts_cts {
struct ufifo_msg_header header;
uint8_t level;
} __attribute__ ((packed));
struct ufifo_msg_mode_change {
struct ufifo_msg_header header;
uint32_t baudrate;
uint32_t config;
} __attribute__ ((packed));
#define UFIFO_MSG_HEADER_SIZE (sizeof(struct ufifo_msg_header))
#define UFIFO_MSG_TXL_BODY_SIZE (sizeof(struct ufifo_msg_tx) - sizeof(struct ufifo_msg_header))
#define UFIFO_MSG_RTS_CTS_BODY_SIZE (sizeof(struct ufifo_msg_rts_cts) - sizeof(struct ufifo_msg_header))
#define UFIFO_MSG_MODE_CHANGE_BODY_SIZE (sizeof(struct ufifo_msg_mode_change) - sizeof(struct ufifo_msg_header))
#define UFIFO_BIGGEST_MSG (sizeof(struct ufifo_msg_mode_change))
#ifdef __cplusplus
}
#endif
#endif /* _NRF_HW_MODEL_UART_H */

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _NRF_HW_MODEL_UART_BACKEND_IF_H
#define _NRF_HW_MODEL_UART_BACKEND_IF_H
#include "bs_types.h"
#include <stdint.h>
#include "NHW_config.h"
#include "NHW_UART.h"
#ifdef __cplusplus
extern "C"{
#endif
/* Interface backends export to main UART module */
typedef void (*tx_byte_ft)(uint inst, uint8_t data);
typedef void (*RTS_pin_toggle_ft)(uint inst, bool new_level);
typedef void (*uart_enable_notify_ft)(uint inst, uint8_t tx_enabled, uint8_t rx_enabled);
struct backend_if {
tx_byte_ft tx_byte_f; /* Note this is called at the beginning of the byte frame*/
RTS_pin_toggle_ft RTS_pin_toggle_f;
uart_enable_notify_ft uart_enable_notify_f;
};
/* Interface UART module exposes to backends */
void nhw_UARTE_digest_Rx_byte(uint inst, uint8_t byte);
bs_time_t nhw_uarte_one_byte_time(uint inst);
void nhw_UARTE_CTS_lowered(uint inst);
void nhw_UARTE_CTS_raised(uint inst);
void nhw_UARTE_backend_register(uint inst, struct backend_if *backend);
#ifdef __cplusplus
}
#endif
#endif /* _NRF_HW_MODEL_UART_BACKEND_IF_H */

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _NRF_HW_MODEL_UART_PRIVATE_H
#define _NRF_HW_MODEL_UART_PRIVATE_H
#include "bs_types.h"
#include <stdint.h>
#include <stdio.h>
#include "NHW_UART_backend_if.h"
#ifdef __cplusplus
extern "C"{
#endif
enum uart_tx_status {Tx_Off = 0,
Tx_Idle,
Tx_Pend /* Waiting for CTS to lower to start Tx'ing */,
Txing,
Tx_Stopping /* Waiting for current frame to finish to finish a TASK STOP */};
enum uarte_dma_status {DMA_Off = 0, DMAing};
enum uart_rx_status {Rx_Off = 0, Rx_turning_off /* Waiting for RX TO */, Rx_On};
#define RX_FIFO_SIZE 6
#define RX_FIFO_RTS_THRESHOLD 2
struct uarte_status {
bs_time_t Rx_TO_timer;
bs_time_t Tx_byte_done_timer;
uint inst;
NRF_UART_Type *UART_regs[NHW_UARTE_TOTAL_INST];
NRF_UARTE_Type *UARTE_regs[NHW_UARTE_TOTAL_INST];
#if (NHW_HAS_DPPI)
/* Mapping of peripheral instance to DPPI instance */
uint dppi_map;
#endif
enum uart_tx_status tx_status;
enum uart_rx_status rx_status;
uint8_t Rx_FIFO[RX_FIFO_SIZE];
int Rx_FIFO_cnt;
uint8_t Tx_byte;
bool RTSR; /* Logical level of RTS/R (false/lowered => Ready to receive)
(this value is internal, and toggles even if the flow-control is disabled) */
bool CTS_blocking; /* CTS is blocking the Tx (i.e. it is high),
* this value toggles even if flow control is disabled */
/* DMA status including internally buffered/shadow version of the corresponding registers */
uint32_t TXD_PTR;
uint32_t TXD_MAXCNT;
uint32_t TXD_AMOUNT;
enum uarte_dma_status tx_dma_status;
uint32_t RXD_PTR;
uint32_t RXD_MAXCNT;
uint32_t RXD_AMOUNT;
enum uarte_dma_status rx_dma_status;
struct backend_if backend;
char *Rx_log_file_name;
char *Tx_log_file_name;
FILE *Tx_log_file;
FILE *Rx_log_file;
uart_rtxb_cb_f trx_callbacks[2];
};
#ifdef __cplusplus
}
#endif
#endif /* _NRF_HW_MODEL_UART_PRIVATE_H */

View File

@ -176,6 +176,16 @@
#define NHW_TIMER_MAX_N_CC 6
#define NHW_TIMER_FREQ {16, 16, 16, 16, 16}
#define NHW_UARTE_TOTAL_INST 2
#define NHW_UART_0 0
#define NHW_UART_1 1
#define NHW_UARTE_INT_MAP {{0 , 2}, \
{0 , 40}, \
} /* Only core, UARTE0_UART0_IRQn, UARTE1_IRQn */
#define NHW_UARTE_HAS_UART 1
#define NHW_UARTE_NAMES {"UATE0", \
"UATE1"}
#define NHW_BSTICKER_TOTAL_INST 1
#define NHW_BSTICKER_TIMER_INT_MAP {{0 , 0}} /*Only core, -*/
@ -428,6 +438,27 @@
#define NHW_TIMER_FREQ {16, 16, 16, 16, 16, 16}
#define NHW_TIMER_DPPI_MAP {0, 0, 0, 1, 1, 1} /*3xApp core, 3xNetwork core*/
#define NHW_UARTE_TOTAL_INST 5
#define NHW_UARTE_APP0 0
#define NHW_UARTE_APP1 1
#define NHW_UARTE_APP2 2
#define NHW_UARTE_APP3 3
#define NHW_UARTE_NET0 4
#define NHW_UARTE_INT_MAP {{0 , 8}, \
{0 , 9}, \
{0 , 11}, \
{0 , 12}, \
{1 , 19}, \
} /* App core, SERIAL0..3_IRQn,
Net core, SERIAL0_IRQn */
#define NHW_UARTE_DPPI_MAP {0, 0, 0, 0, 1} /*4xApp core, 1xNetwork core*/
#define NHW_UARTE_HAS_UART 0
#define NHW_UARTE_NAMES {"App UATE0", \
"App UATE1", \
"App UATE2", \
"App UATE3", \
"Net UATE0"}
#define NHW_FAKE_TIMER_TOTAL_INST 2
#define NHW_FAKE_TIMER_INT_MAP {{0 , 0}, \
{1 , 0}} /*App core & Net core, -*/

View File

@ -27,6 +27,14 @@
} \
}
#define NHW_SIDEEFFECTS_TASKS(peri, peri_regs, task) \
void nhw_##peri##_regw_sideeffects_TASKS_##task(unsigned int inst) { \
if ( peri_regs TASKS_##task ) { \
peri_regs TASKS_##task = 0; \
nhw_##peri##_TASK_##task(inst); \
} \
}
/*
* SUBSCRIBE register write side-effects
*/
@ -58,6 +66,14 @@
peri_regs PUBLISH_##event)
#endif /* (NHW_HAS_PPI) / (NHW_HAS_DPPI)*/
#define _NHW_SIGNAL_EVENT_body(peri, peri_regs, event) \
{ \
peri_regs EVENTS_##event = 1; \
nhw_##peri##_eval_interrupt(inst); \
_NHW_XPPI_EVENT(peri, peri_regs, inst, event); \
}
/*
* Signal an event:
* * Set the corresponding event register
@ -65,24 +81,21 @@
* * Send the event either to the PPI or DPPI (if enabled)
*
* NOTE: Cannot be used for events with shortcuts
* NOTE: Cannot be used for multi-instance peripherals connected to the PPI
*/
#define NHW_SIGNAL_EVENT(peri, peri_regs, event) \
void nhw_##peri##_signal_EVENTS_##event(unsigned int inst) { \
peri_regs EVENTS_##event = 1; \
nhw_##peri##_eval_interrupt(inst); \
_NHW_XPPI_EVENT(peri, peri_regs, inst, event); \
}
void nhw_##peri##_signal_EVENTS_##event(unsigned int inst) \
_NHW_SIGNAL_EVENT_body(peri, peri_regs, event)
/*
* Signal an event. Like NHW_SIGNAL_EVENT()
* but when the event has shortcuts.
*
* NOTE: Cannot be used for multi-instance peripherals connected to the PPI
*/
#define NHW_SIGNAL_EVENT_ns(peri, peri_regs, event) \
void nhw_##peri##_signal_EVENTS_##event##_noshort(unsigned int inst) { \
peri_regs EVENTS_##event = 1; \
nhw_##peri##_eval_interrupt(inst); \
_NHW_XPPI_EVENT(peri, peri_regs, inst, event); \
}
void nhw_##peri##_signal_EVENTS_##event##_noshort(unsigned int inst) \
_NHW_SIGNAL_EVENT_body(peri, peri_regs, event)
#define NHW_SIGNAL_EVENT_si(peri, event) \
NHW_SIGNAL_EVENT(peri, NRF_##peri##_regs. , event)
@ -134,6 +147,11 @@
} \
}
#define NHW_CHECK_INTERRUPT(peri, peri_regs, event, inten) \
if (peri_regs EVENTS_##event && (inten & peri##_INTENSET_##event##_Msk)){ \
new_int_line = true; \
}
#define NHW_CHECK_INTERRUPT_si(peri, event, inten) \
if (NRF_##peri##_regs.EVENTS_##event && (inten & peri##_INTENSET_##event##_Msk)){ \
new_int_line = true; \
@ -144,4 +162,9 @@
nhw_##peri##_TASK_##task(); \
}
#define NHW_SHORT(peri, inst, peri_regs, event, task) \
if (peri_regs SHORTS & peri##_SHORTS_##event##_##task##_Msk) { \
nhw_##peri##_TASK_##task(inst); \
}
#endif /* _NRF_HW_MODEL_NHW_TEMPLATES_H */

View File

@ -149,6 +149,48 @@ typedef struct {
} RESET_NETWORK_Type; /*!< Size = 8 (0x8) */
/**
* @brief UART_PSEL [PSEL] (Unspecified)
*/
typedef struct {
__IOM uint32_t RTS; /*!< (@ 0x00000000) Pin select for RTS */
__IOM uint32_t TXD; /*!< (@ 0x00000004) Pin select for TXD */
__IOM uint32_t CTS; /*!< (@ 0x00000008) Pin select for CTS */
__IOM uint32_t RXD; /*!< (@ 0x0000000C) Pin select for RXD */
} UART_PSEL_Type; /*!< Size = 16 (0x10) */
/**
* @brief UARTE_PSEL [PSEL] (Unspecified)
*/
typedef struct {
__IOM uint32_t RTS; /*!< (@ 0x00000000) Pin select for RTS signal */
__IOM uint32_t TXD; /*!< (@ 0x00000004) Pin select for TXD signal */
__IOM uint32_t CTS; /*!< (@ 0x00000008) Pin select for CTS signal */
__IOM uint32_t RXD; /*!< (@ 0x0000000C) Pin select for RXD signal */
} UARTE_PSEL_Type; /*!< Size = 16 (0x10) */
/**
* @brief UARTE_RXD [RXD] (RXD EasyDMA channel)
*/
typedef struct {
__IOM uint32_t PTR; /*!< (@ 0x00000000) Data pointer */
__IOM uint32_t MAXCNT; /*!< (@ 0x00000004) Maximum number of bytes in receive buffer */
__IM uint32_t AMOUNT; /*!< (@ 0x00000008) Number of bytes transferred in the last transaction */
} UARTE_RXD_Type; /*!< Size = 12 (0xc) */
/**
* @brief UARTE_TXD [TXD] (TXD EasyDMA channel)
*/
typedef struct {
__IOM uint32_t PTR; /*!< (@ 0x00000000) Data pointer */
__IOM uint32_t MAXCNT; /*!< (@ 0x00000004) Maximum number of bytes in transmit buffer */
__IM uint32_t AMOUNT; /*!< (@ 0x00000008) Number of bytes transferred in the last transaction */
} UARTE_TXD_Type; /*!< Size = 12 (0xc) */
/**
* @brief VREQCTRL_VREGRADIO [VREGRADIO] (Unspecified)
*/
@ -5507,6 +5549,622 @@ typedef struct { /*!< (@ 0x4100C000) TIMER0_NS St
#define TIMER_ONESHOTEN_ONESHOTEN_Disable (0UL) /*!< Disable one-shot operation */
#define TIMER_ONESHOTEN_ONESHOTEN_Enable (1UL) /*!< Enable one-shot operation */
/* =========================================================================================================================== */
/* ================ UART0 ================ */
/* =========================================================================================================================== */
/**
* @brief Universal Asynchronous Receiver/Transmitter (UART0)
*/
typedef struct { /*!< (@ 0x40002000) UART0 Structure */
__OM uint32_t TASKS_STARTRX; /*!< (@ 0x00000000) Start UART receiver */
__OM uint32_t TASKS_STOPRX; /*!< (@ 0x00000004) Stop UART receiver */
__OM uint32_t TASKS_STARTTX; /*!< (@ 0x00000008) Start UART transmitter */
__OM uint32_t TASKS_STOPTX; /*!< (@ 0x0000000C) Stop UART transmitter */
__IM uint32_t RESERVED[3];
__OM uint32_t TASKS_SUSPEND; /*!< (@ 0x0000001C) Suspend UART */
__IM uint32_t RESERVED1[56];
__IOM uint32_t EVENTS_CTS; /*!< (@ 0x00000100) CTS is activated (set low). Clear To Send. */
__IOM uint32_t EVENTS_NCTS; /*!< (@ 0x00000104) CTS is deactivated (set high). Not Clear To Send. */
__IOM uint32_t EVENTS_RXDRDY; /*!< (@ 0x00000108) Data received in RXD */
__IM uint32_t RESERVED2[4];
__IOM uint32_t EVENTS_TXDRDY; /*!< (@ 0x0000011C) Data sent from TXD */
__IM uint32_t RESERVED3;
__IOM uint32_t EVENTS_ERROR; /*!< (@ 0x00000124) Error detected */
__IM uint32_t RESERVED4[7];
__IOM uint32_t EVENTS_RXTO; /*!< (@ 0x00000144) Receiver timeout */
__IM uint32_t RESERVED5[46];
__IOM uint32_t SHORTS; /*!< (@ 0x00000200) Shortcuts between local events and tasks */
__IM uint32_t RESERVED6[64];
__IOM uint32_t INTENSET; /*!< (@ 0x00000304) Enable interrupt */
__IOM uint32_t INTENCLR; /*!< (@ 0x00000308) Disable interrupt */
__IM uint32_t RESERVED7[93];
__IOM uint32_t ERRORSRC; /*!< (@ 0x00000480) Error source */
__IM uint32_t RESERVED8[31];
__IOM uint32_t ENABLE; /*!< (@ 0x00000500) Enable UART */
__IM uint32_t RESERVED9;
__IOM UART_PSEL_Type PSEL; /*!< (@ 0x00000508) Unspecified */
__IM uint32_t RXD; /*!< (@ 0x00000518) RXD register */
__OM uint32_t TXD; /*!< (@ 0x0000051C) TXD register */
__IM uint32_t RESERVED10;
__IOM uint32_t BAUDRATE; /*!< (@ 0x00000524) Baud rate. Accuracy depends on the HFCLK source
selected. */
__IM uint32_t RESERVED11[17];
__IOM uint32_t CONFIG; /*!< (@ 0x0000056C) Configuration of parity and hardware flow control */
} NRF_UART_Type; /*!< Size = 1392 (0x570) */
/* Peripheral: UART */
/* Description: Universal Asynchronous Receiver/Transmitter */
/* Register: UART_SHORTS */
/* Description: Shortcuts between local events and tasks */
/* Bit 4 : Shortcut between event NCTS and task STOPRX */
#define UART_SHORTS_NCTS_STOPRX_Pos (4UL) /*!< Position of NCTS_STOPRX field. */
#define UART_SHORTS_NCTS_STOPRX_Msk (0x1UL << UART_SHORTS_NCTS_STOPRX_Pos) /*!< Bit mask of NCTS_STOPRX field. */
#define UART_SHORTS_NCTS_STOPRX_Disabled (0UL) /*!< Disable shortcut */
#define UART_SHORTS_NCTS_STOPRX_Enabled (1UL) /*!< Enable shortcut */
/* Bit 3 : Shortcut between event CTS and task STARTRX */
#define UART_SHORTS_CTS_STARTRX_Pos (3UL) /*!< Position of CTS_STARTRX field. */
#define UART_SHORTS_CTS_STARTRX_Msk (0x1UL << UART_SHORTS_CTS_STARTRX_Pos) /*!< Bit mask of CTS_STARTRX field. */
#define UART_SHORTS_CTS_STARTRX_Disabled (0UL) /*!< Disable shortcut */
#define UART_SHORTS_CTS_STARTRX_Enabled (1UL) /*!< Enable shortcut */
/* Register: UART_ERRORSRC */
/* Description: Error source */
/* Bit 3 : Break condition */
#define UART_ERRORSRC_BREAK_Pos (3UL) /*!< Position of BREAK field. */
#define UART_ERRORSRC_BREAK_Msk (0x1UL << UART_ERRORSRC_BREAK_Pos) /*!< Bit mask of BREAK field. */
#define UART_ERRORSRC_BREAK_NotPresent (0UL) /*!< Read: error not present */
#define UART_ERRORSRC_BREAK_Present (1UL) /*!< Read: error present */
/* Bit 2 : Framing error occurred */
#define UART_ERRORSRC_FRAMING_Pos (2UL) /*!< Position of FRAMING field. */
#define UART_ERRORSRC_FRAMING_Msk (0x1UL << UART_ERRORSRC_FRAMING_Pos) /*!< Bit mask of FRAMING field. */
#define UART_ERRORSRC_FRAMING_NotPresent (0UL) /*!< Read: error not present */
#define UART_ERRORSRC_FRAMING_Present (1UL) /*!< Read: error present */
/* Bit 1 : Parity error */
#define UART_ERRORSRC_PARITY_Pos (1UL) /*!< Position of PARITY field. */
#define UART_ERRORSRC_PARITY_Msk (0x1UL << UART_ERRORSRC_PARITY_Pos) /*!< Bit mask of PARITY field. */
#define UART_ERRORSRC_PARITY_NotPresent (0UL) /*!< Read: error not present */
#define UART_ERRORSRC_PARITY_Present (1UL) /*!< Read: error present */
/* Bit 0 : Overrun error */
#define UART_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */
#define UART_ERRORSRC_OVERRUN_Msk (0x1UL << UART_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */
#define UART_ERRORSRC_OVERRUN_NotPresent (0UL) /*!< Read: error not present */
#define UART_ERRORSRC_OVERRUN_Present (1UL) /*!< Read: error present */
/* Register: UART_ENABLE */
/* Description: Enable UART */
/* Bits 3..0 : Enable or disable UART */
#define UART_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
#define UART_ENABLE_ENABLE_Msk (0xFUL << UART_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
#define UART_ENABLE_ENABLE_Disabled (0UL) /*!< Disable UART */
#define UART_ENABLE_ENABLE_Enabled (4UL) /*!< Enable UART */
/* Register: UART_PSEL_RTS */
/* Description: Pin select for RTS */
/* Bit 31 : Connection */
#define UART_PSEL_RTS_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */
#define UART_PSEL_RTS_CONNECT_Msk (0x1UL << UART_PSEL_RTS_CONNECT_Pos) /*!< Bit mask of CONNECT field. */
#define UART_PSEL_RTS_CONNECT_Connected (0UL) /*!< Connect */
#define UART_PSEL_RTS_CONNECT_Disconnected (1UL) /*!< Disconnect */
/* Bit 5 : Port number */
#define UART_PSEL_RTS_PORT_Pos (5UL) /*!< Position of PORT field. */
#define UART_PSEL_RTS_PORT_Msk (0x1UL << UART_PSEL_RTS_PORT_Pos) /*!< Bit mask of PORT field. */
/* Bits 4..0 : Pin number */
#define UART_PSEL_RTS_PIN_Pos (0UL) /*!< Position of PIN field. */
#define UART_PSEL_RTS_PIN_Msk (0x1FUL << UART_PSEL_RTS_PIN_Pos) /*!< Bit mask of PIN field. */
/* Register: UART_PSEL_TXD */
/* Description: Pin select for TXD */
/* Bit 31 : Connection */
#define UART_PSEL_TXD_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */
#define UART_PSEL_TXD_CONNECT_Msk (0x1UL << UART_PSEL_TXD_CONNECT_Pos) /*!< Bit mask of CONNECT field. */
#define UART_PSEL_TXD_CONNECT_Connected (0UL) /*!< Connect */
#define UART_PSEL_TXD_CONNECT_Disconnected (1UL) /*!< Disconnect */
/* Bit 5 : Port number */
#define UART_PSEL_TXD_PORT_Pos (5UL) /*!< Position of PORT field. */
#define UART_PSEL_TXD_PORT_Msk (0x1UL << UART_PSEL_TXD_PORT_Pos) /*!< Bit mask of PORT field. */
/* Bits 4..0 : Pin number */
#define UART_PSEL_TXD_PIN_Pos (0UL) /*!< Position of PIN field. */
#define UART_PSEL_TXD_PIN_Msk (0x1FUL << UART_PSEL_TXD_PIN_Pos) /*!< Bit mask of PIN field. */
/* Register: UART_PSEL_CTS */
/* Description: Pin select for CTS */
/* Bit 31 : Connection */
#define UART_PSEL_CTS_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */
#define UART_PSEL_CTS_CONNECT_Msk (0x1UL << UART_PSEL_CTS_CONNECT_Pos) /*!< Bit mask of CONNECT field. */
#define UART_PSEL_CTS_CONNECT_Connected (0UL) /*!< Connect */
#define UART_PSEL_CTS_CONNECT_Disconnected (1UL) /*!< Disconnect */
/* Bit 5 : Port number */
#define UART_PSEL_CTS_PORT_Pos (5UL) /*!< Position of PORT field. */
#define UART_PSEL_CTS_PORT_Msk (0x1UL << UART_PSEL_CTS_PORT_Pos) /*!< Bit mask of PORT field. */
/* Bits 4..0 : Pin number */
#define UART_PSEL_CTS_PIN_Pos (0UL) /*!< Position of PIN field. */
#define UART_PSEL_CTS_PIN_Msk (0x1FUL << UART_PSEL_CTS_PIN_Pos) /*!< Bit mask of PIN field. */
/* Register: UART_PSEL_RXD */
/* Description: Pin select for RXD */
/* Bit 31 : Connection */
#define UART_PSEL_RXD_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */
#define UART_PSEL_RXD_CONNECT_Msk (0x1UL << UART_PSEL_RXD_CONNECT_Pos) /*!< Bit mask of CONNECT field. */
#define UART_PSEL_RXD_CONNECT_Connected (0UL) /*!< Connect */
#define UART_PSEL_RXD_CONNECT_Disconnected (1UL) /*!< Disconnect */
/* Bit 5 : Port number */
#define UART_PSEL_RXD_PORT_Pos (5UL) /*!< Position of PORT field. */
#define UART_PSEL_RXD_PORT_Msk (0x1UL << UART_PSEL_RXD_PORT_Pos) /*!< Bit mask of PORT field. */
/* Bits 4..0 : Pin number */
#define UART_PSEL_RXD_PIN_Pos (0UL) /*!< Position of PIN field. */
#define UART_PSEL_RXD_PIN_Msk (0x1FUL << UART_PSEL_RXD_PIN_Pos) /*!< Bit mask of PIN field. */
/* Register: UART_RXD */
/* Description: RXD register */
/* Bits 7..0 : RX data received in previous transfers, double buffered */
#define UART_RXD_RXD_Pos (0UL) /*!< Position of RXD field. */
#define UART_RXD_RXD_Msk (0xFFUL << UART_RXD_RXD_Pos) /*!< Bit mask of RXD field. */
/* Register: UART_TXD */
/* Description: TXD register */
/* Bits 7..0 : TX data to be transferred */
#define UART_TXD_TXD_Pos (0UL) /*!< Position of TXD field. */
#define UART_TXD_TXD_Msk (0xFFUL << UART_TXD_TXD_Pos) /*!< Bit mask of TXD field. */
/* Register: UART_BAUDRATE */
/* Description: Baud rate. Accuracy depends on the HFCLK source selected. */
/* Bits 31..0 : Baud rate */
#define UART_BAUDRATE_BAUDRATE_Pos (0UL) /*!< Position of BAUDRATE field. */
#define UART_BAUDRATE_BAUDRATE_Msk (0xFFFFFFFFUL << UART_BAUDRATE_BAUDRATE_Pos) /*!< Bit mask of BAUDRATE field. */
#define UART_BAUDRATE_BAUDRATE_Baud1200 (0x0004F000UL) /*!< 1200 baud (actual rate: 1205) */
#define UART_BAUDRATE_BAUDRATE_Baud2400 (0x0009D000UL) /*!< 2400 baud (actual rate: 2396) */
#define UART_BAUDRATE_BAUDRATE_Baud4800 (0x0013B000UL) /*!< 4800 baud (actual rate: 4808) */
#define UART_BAUDRATE_BAUDRATE_Baud9600 (0x00275000UL) /*!< 9600 baud (actual rate: 9598) */
#define UART_BAUDRATE_BAUDRATE_Baud14400 (0x003B0000UL) /*!< 14400 baud (actual rate: 14414) */
#define UART_BAUDRATE_BAUDRATE_Baud19200 (0x004EA000UL) /*!< 19200 baud (actual rate: 19208) */
#define UART_BAUDRATE_BAUDRATE_Baud28800 (0x0075F000UL) /*!< 28800 baud (actual rate: 28829) */
#define UART_BAUDRATE_BAUDRATE_Baud31250 (0x00800000UL) /*!< 31250 baud */
#define UART_BAUDRATE_BAUDRATE_Baud38400 (0x009D5000UL) /*!< 38400 baud (actual rate: 38462) */
#define UART_BAUDRATE_BAUDRATE_Baud56000 (0x00E50000UL) /*!< 56000 baud (actual rate: 55944) */
#define UART_BAUDRATE_BAUDRATE_Baud57600 (0x00EBF000UL) /*!< 57600 baud (actual rate: 57762) */
#define UART_BAUDRATE_BAUDRATE_Baud76800 (0x013A9000UL) /*!< 76800 baud (actual rate: 76923) */
#define UART_BAUDRATE_BAUDRATE_Baud115200 (0x01D7E000UL) /*!< 115200 baud (actual rate: 115942) */
#define UART_BAUDRATE_BAUDRATE_Baud230400 (0x03AFB000UL) /*!< 230400 baud (actual rate: 231884) */
#define UART_BAUDRATE_BAUDRATE_Baud250000 (0x04000000UL) /*!< 250000 baud */
#define UART_BAUDRATE_BAUDRATE_Baud460800 (0x075F7000UL) /*!< 460800 baud (actual rate: 470588) */
#define UART_BAUDRATE_BAUDRATE_Baud921600 (0x0EBED000UL) /*!< 921600 baud (actual rate: 941176) */
#define UART_BAUDRATE_BAUDRATE_Baud1M (0x10000000UL) /*!< 1Mega baud */
/* Register: UART_CONFIG */
/* Description: Configuration of parity and hardware flow control */
/* Bit 8 : Even or odd parity type */
#define UART_CONFIG_PARITYTYPE_Pos (8UL) /*!< Position of PARITYTYPE field. */
#define UART_CONFIG_PARITYTYPE_Msk (0x1UL << UART_CONFIG_PARITYTYPE_Pos) /*!< Bit mask of PARITYTYPE field. */
#define UART_CONFIG_PARITYTYPE_Even (0UL) /*!< Even parity */
#define UART_CONFIG_PARITYTYPE_Odd (1UL) /*!< Odd parity */
/* Bit 4 : Stop bits */
#define UART_CONFIG_STOP_Pos (4UL) /*!< Position of STOP field. */
#define UART_CONFIG_STOP_Msk (0x1UL << UART_CONFIG_STOP_Pos) /*!< Bit mask of STOP field. */
#define UART_CONFIG_STOP_One (0UL) /*!< One stop bit */
#define UART_CONFIG_STOP_Two (1UL) /*!< Two stop bits */
/* Bits 3..1 : Parity */
#define UART_CONFIG_PARITY_Pos (1UL) /*!< Position of PARITY field. */
#define UART_CONFIG_PARITY_Msk (0x7UL << UART_CONFIG_PARITY_Pos) /*!< Bit mask of PARITY field. */
#define UART_CONFIG_PARITY_Excluded (0x0UL) /*!< Exclude parity bit */
#define UART_CONFIG_PARITY_Included (0x7UL) /*!< Include parity bit */
/* Bit 0 : Hardware flow control */
#define UART_CONFIG_HWFC_Pos (0UL) /*!< Position of HWFC field. */
#define UART_CONFIG_HWFC_Msk (0x1UL << UART_CONFIG_HWFC_Pos) /*!< Bit mask of HWFC field. */
#define UART_CONFIG_HWFC_Disabled (0UL) /*!< Disabled */
#define UART_CONFIG_HWFC_Enabled (1UL) /*!< Enabled */
/* =========================================================================================================================== */
/* ================ UARTE0_NS ================ */
/* =========================================================================================================================== */
/**
* @brief UART with EasyDMA 0 (UARTE0_NS)
*/
typedef struct { /*!< (@ 0x40008000) UARTE0_NS Structure */
__OM uint32_t TASKS_STARTRX; /*!< (@ 0x00000000) Start UART receiver */
__OM uint32_t TASKS_STOPRX; /*!< (@ 0x00000004) Stop UART receiver */
__OM uint32_t TASKS_STARTTX; /*!< (@ 0x00000008) Start UART transmitter */
__OM uint32_t TASKS_STOPTX; /*!< (@ 0x0000000C) Stop UART transmitter */
__IM uint32_t RESERVED[7];
__OM uint32_t TASKS_FLUSHRX; /*!< (@ 0x0000002C) Flush RX FIFO into RX buffer */
__IM uint32_t RESERVED1[20];
__IOM uint32_t SUBSCRIBE_STARTRX; /*!< (@ 0x00000080) Subscribe configuration for task STARTRX */
__IOM uint32_t SUBSCRIBE_STOPRX; /*!< (@ 0x00000084) Subscribe configuration for task STOPRX */
__IOM uint32_t SUBSCRIBE_STARTTX; /*!< (@ 0x00000088) Subscribe configuration for task STARTTX */
__IOM uint32_t SUBSCRIBE_STOPTX; /*!< (@ 0x0000008C) Subscribe configuration for task STOPTX */
__IM uint32_t RESERVED2[7];
__IOM uint32_t SUBSCRIBE_FLUSHRX; /*!< (@ 0x000000AC) Subscribe configuration for task FLUSHRX */
__IM uint32_t RESERVED3[20];
__IOM uint32_t EVENTS_CTS; /*!< (@ 0x00000100) CTS is activated (set low). Clear To Send. */
__IOM uint32_t EVENTS_NCTS; /*!< (@ 0x00000104) CTS is deactivated (set high). Not Clear To Send. */
__IOM uint32_t EVENTS_RXDRDY; /*!< (@ 0x00000108) Data received in RXD (but potentially not yet
transferred to Data RAM) */
__IM uint32_t RESERVED4;
__IOM uint32_t EVENTS_ENDRX; /*!< (@ 0x00000110) Receive buffer is filled up */
__IM uint32_t RESERVED5[2];
__IOM uint32_t EVENTS_TXDRDY; /*!< (@ 0x0000011C) Data sent from TXD */
__IOM uint32_t EVENTS_ENDTX; /*!< (@ 0x00000120) Last TX byte transmitted */
__IOM uint32_t EVENTS_ERROR; /*!< (@ 0x00000124) Error detected */
__IM uint32_t RESERVED6[7];
__IOM uint32_t EVENTS_RXTO; /*!< (@ 0x00000144) Receiver timeout */
__IM uint32_t RESERVED7;
__IOM uint32_t EVENTS_RXSTARTED; /*!< (@ 0x0000014C) UART receiver has started */
__IOM uint32_t EVENTS_TXSTARTED; /*!< (@ 0x00000150) UART transmitter has started */
__IM uint32_t RESERVED8;
__IOM uint32_t EVENTS_TXSTOPPED; /*!< (@ 0x00000158) Transmitter stopped */
__IM uint32_t RESERVED9[9];
__IOM uint32_t PUBLISH_CTS; /*!< (@ 0x00000180) Publish configuration for event CTS */
__IOM uint32_t PUBLISH_NCTS; /*!< (@ 0x00000184) Publish configuration for event NCTS */
__IOM uint32_t PUBLISH_RXDRDY; /*!< (@ 0x00000188) Publish configuration for event RXDRDY */
__IM uint32_t RESERVED10;
__IOM uint32_t PUBLISH_ENDRX; /*!< (@ 0x00000190) Publish configuration for event ENDRX */
__IM uint32_t RESERVED11[2];
__IOM uint32_t PUBLISH_TXDRDY; /*!< (@ 0x0000019C) Publish configuration for event TXDRDY */
__IOM uint32_t PUBLISH_ENDTX; /*!< (@ 0x000001A0) Publish configuration for event ENDTX */
__IOM uint32_t PUBLISH_ERROR; /*!< (@ 0x000001A4) Publish configuration for event ERROR */
__IM uint32_t RESERVED12[7];
__IOM uint32_t PUBLISH_RXTO; /*!< (@ 0x000001C4) Publish configuration for event RXTO */
__IM uint32_t RESERVED13;
__IOM uint32_t PUBLISH_RXSTARTED; /*!< (@ 0x000001CC) Publish configuration for event RXSTARTED */
__IOM uint32_t PUBLISH_TXSTARTED; /*!< (@ 0x000001D0) Publish configuration for event TXSTARTED */
__IM uint32_t RESERVED14;
__IOM uint32_t PUBLISH_TXSTOPPED; /*!< (@ 0x000001D8) Publish configuration for event TXSTOPPED */
__IM uint32_t RESERVED15[9];
__IOM uint32_t SHORTS; /*!< (@ 0x00000200) Shortcuts between local events and tasks */
__IM uint32_t RESERVED16[63];
__IOM uint32_t INTEN; /*!< (@ 0x00000300) Enable or disable interrupt */
__IOM uint32_t INTENSET; /*!< (@ 0x00000304) Enable interrupt */
__IOM uint32_t INTENCLR; /*!< (@ 0x00000308) Disable interrupt */
__IM uint32_t RESERVED17[93];
__IOM uint32_t ERRORSRC; /*!< (@ 0x00000480) Error source */
__IM uint32_t RESERVED18[31];
__IOM uint32_t ENABLE; /*!< (@ 0x00000500) Enable UART */
__IM uint32_t RESERVED19;
__IOM UARTE_PSEL_Type PSEL; /*!< (@ 0x00000508) Unspecified */
__IM uint32_t RESERVED20[3];
__IOM uint32_t BAUDRATE; /*!< (@ 0x00000524) Baud rate. Accuracy depends on the HFCLK source
selected. */
__IM uint32_t RESERVED21[3];
__IOM UARTE_RXD_Type RXD; /*!< (@ 0x00000534) RXD EasyDMA channel */
__IM uint32_t RESERVED22;
__IOM UARTE_TXD_Type TXD; /*!< (@ 0x00000544) TXD EasyDMA channel */
__IM uint32_t RESERVED23[7];
__IOM uint32_t CONFIG; /*!< (@ 0x0000056C) Configuration of parity and hardware flow control */
} NRF_UARTE_Type; /*!< Size = 1392 (0x570) */
/* Peripheral: UARTE */
/* Description: UART with EasyDMA 0 */
/* Register: UARTE_SHORTS */
/* Description: Shortcuts between local events and tasks */
/* Bit 6 : Shortcut between event ENDRX and task STOPRX */
#define UARTE_SHORTS_ENDRX_STOPRX_Pos (6UL) /*!< Position of ENDRX_STOPRX field. */
#define UARTE_SHORTS_ENDRX_STOPRX_Msk (0x1UL << UARTE_SHORTS_ENDRX_STOPRX_Pos) /*!< Bit mask of ENDRX_STOPRX field. */
#define UARTE_SHORTS_ENDRX_STOPRX_Disabled (0UL) /*!< Disable shortcut */
#define UARTE_SHORTS_ENDRX_STOPRX_Enabled (1UL) /*!< Enable shortcut */
/* Bit 5 : Shortcut between event ENDRX and task STARTRX */
#define UARTE_SHORTS_ENDRX_STARTRX_Pos (5UL) /*!< Position of ENDRX_STARTRX field. */
#define UARTE_SHORTS_ENDRX_STARTRX_Msk (0x1UL << UARTE_SHORTS_ENDRX_STARTRX_Pos) /*!< Bit mask of ENDRX_STARTRX field. */
#define UARTE_SHORTS_ENDRX_STARTRX_Disabled (0UL) /*!< Disable shortcut */
#define UARTE_SHORTS_ENDRX_STARTRX_Enabled (1UL) /*!< Enable shortcut */
/* Register: UARTE_INTENSET */
/* Description: Enable interrupt */
/* Bit 22 : Write '1' to enable interrupt for event TXSTOPPED */
#define UARTE_INTENSET_TXSTOPPED_Pos (22UL) /*!< Position of TXSTOPPED field. */
#define UARTE_INTENSET_TXSTOPPED_Msk (0x1UL << UARTE_INTENSET_TXSTOPPED_Pos) /*!< Bit mask of TXSTOPPED field. */
#define UARTE_INTENSET_TXSTOPPED_Disabled (0UL) /*!< Read: Disabled */
#define UARTE_INTENSET_TXSTOPPED_Enabled (1UL) /*!< Read: Enabled */
#define UARTE_INTENSET_TXSTOPPED_Set (1UL) /*!< Enable */
/* Bit 20 : Write '1' to enable interrupt for event TXSTARTED */
#define UARTE_INTENSET_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */
#define UARTE_INTENSET_TXSTARTED_Msk (0x1UL << UARTE_INTENSET_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */
#define UARTE_INTENSET_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */
#define UARTE_INTENSET_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */
#define UARTE_INTENSET_TXSTARTED_Set (1UL) /*!< Enable */
/* Bit 19 : Write '1' to enable interrupt for event RXSTARTED */
#define UARTE_INTENSET_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */
#define UARTE_INTENSET_RXSTARTED_Msk (0x1UL << UARTE_INTENSET_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */
#define UARTE_INTENSET_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */
#define UARTE_INTENSET_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */
#define UARTE_INTENSET_RXSTARTED_Set (1UL) /*!< Enable */
/* Bit 17 : Write '1' to enable interrupt for event RXTO */
#define UARTE_INTENSET_RXTO_Pos (17UL) /*!< Position of RXTO field. */
#define UARTE_INTENSET_RXTO_Msk (0x1UL << UARTE_INTENSET_RXTO_Pos) /*!< Bit mask of RXTO field. */
#define UARTE_INTENSET_RXTO_Disabled (0UL) /*!< Read: Disabled */
#define UARTE_INTENSET_RXTO_Enabled (1UL) /*!< Read: Enabled */
#define UARTE_INTENSET_RXTO_Set (1UL) /*!< Enable */
/* Bit 9 : Write '1' to enable interrupt for event ERROR */
#define UARTE_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */
#define UARTE_INTENSET_ERROR_Msk (0x1UL << UARTE_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */
#define UARTE_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */
#define UARTE_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */
#define UARTE_INTENSET_ERROR_Set (1UL) /*!< Enable */
/* Bit 8 : Write '1' to enable interrupt for event ENDTX */
#define UARTE_INTENSET_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */
#define UARTE_INTENSET_ENDTX_Msk (0x1UL << UARTE_INTENSET_ENDTX_Pos) /*!< Bit mask of ENDTX field. */
#define UARTE_INTENSET_ENDTX_Disabled (0UL) /*!< Read: Disabled */
#define UARTE_INTENSET_ENDTX_Enabled (1UL) /*!< Read: Enabled */
#define UARTE_INTENSET_ENDTX_Set (1UL) /*!< Enable */
/* Bit 7 : Write '1' to enable interrupt for event TXDRDY */
#define UARTE_INTENSET_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */
#define UARTE_INTENSET_TXDRDY_Msk (0x1UL << UARTE_INTENSET_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */
#define UARTE_INTENSET_TXDRDY_Disabled (0UL) /*!< Read: Disabled */
#define UARTE_INTENSET_TXDRDY_Enabled (1UL) /*!< Read: Enabled */
#define UARTE_INTENSET_TXDRDY_Set (1UL) /*!< Enable */
/* Bit 4 : Write '1' to enable interrupt for event ENDRX */
#define UARTE_INTENSET_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */
#define UARTE_INTENSET_ENDRX_Msk (0x1UL << UARTE_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */
#define UARTE_INTENSET_ENDRX_Disabled (0UL) /*!< Read: Disabled */
#define UARTE_INTENSET_ENDRX_Enabled (1UL) /*!< Read: Enabled */
#define UARTE_INTENSET_ENDRX_Set (1UL) /*!< Enable */
/* Bit 2 : Write '1' to enable interrupt for event RXDRDY */
#define UARTE_INTENSET_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */
#define UARTE_INTENSET_RXDRDY_Msk (0x1UL << UARTE_INTENSET_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */
#define UARTE_INTENSET_RXDRDY_Disabled (0UL) /*!< Read: Disabled */
#define UARTE_INTENSET_RXDRDY_Enabled (1UL) /*!< Read: Enabled */
#define UARTE_INTENSET_RXDRDY_Set (1UL) /*!< Enable */
/* Bit 1 : Write '1' to enable interrupt for event NCTS */
#define UARTE_INTENSET_NCTS_Pos (1UL) /*!< Position of NCTS field. */
#define UARTE_INTENSET_NCTS_Msk (0x1UL << UARTE_INTENSET_NCTS_Pos) /*!< Bit mask of NCTS field. */
#define UARTE_INTENSET_NCTS_Disabled (0UL) /*!< Read: Disabled */
#define UARTE_INTENSET_NCTS_Enabled (1UL) /*!< Read: Enabled */
#define UARTE_INTENSET_NCTS_Set (1UL) /*!< Enable */
/* Bit 0 : Write '1' to enable interrupt for event CTS */
#define UARTE_INTENSET_CTS_Pos (0UL) /*!< Position of CTS field. */
#define UARTE_INTENSET_CTS_Msk (0x1UL << UARTE_INTENSET_CTS_Pos) /*!< Bit mask of CTS field. */
#define UARTE_INTENSET_CTS_Disabled (0UL) /*!< Read: Disabled */
#define UARTE_INTENSET_CTS_Enabled (1UL) /*!< Read: Enabled */
#define UARTE_INTENSET_CTS_Set (1UL) /*!< Enable */
/* Register: UARTE_ERRORSRC */
/* Description: Error source This register is read/write one to clear. */
/* Bit 3 : Break condition */
#define UARTE_ERRORSRC_BREAK_Pos (3UL) /*!< Position of BREAK field. */
#define UARTE_ERRORSRC_BREAK_Msk (0x1UL << UARTE_ERRORSRC_BREAK_Pos) /*!< Bit mask of BREAK field. */
#define UARTE_ERRORSRC_BREAK_NotPresent (0UL) /*!< Read: error not present */
#define UARTE_ERRORSRC_BREAK_Present (1UL) /*!< Read: error present */
/* Bit 2 : Framing error occurred */
#define UARTE_ERRORSRC_FRAMING_Pos (2UL) /*!< Position of FRAMING field. */
#define UARTE_ERRORSRC_FRAMING_Msk (0x1UL << UARTE_ERRORSRC_FRAMING_Pos) /*!< Bit mask of FRAMING field. */
#define UARTE_ERRORSRC_FRAMING_NotPresent (0UL) /*!< Read: error not present */
#define UARTE_ERRORSRC_FRAMING_Present (1UL) /*!< Read: error present */
/* Bit 1 : Parity error */
#define UARTE_ERRORSRC_PARITY_Pos (1UL) /*!< Position of PARITY field. */
#define UARTE_ERRORSRC_PARITY_Msk (0x1UL << UARTE_ERRORSRC_PARITY_Pos) /*!< Bit mask of PARITY field. */
#define UARTE_ERRORSRC_PARITY_NotPresent (0UL) /*!< Read: error not present */
#define UARTE_ERRORSRC_PARITY_Present (1UL) /*!< Read: error present */
/* Bit 0 : Overrun error */
#define UARTE_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */
#define UARTE_ERRORSRC_OVERRUN_Msk (0x1UL << UARTE_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */
#define UARTE_ERRORSRC_OVERRUN_NotPresent (0UL) /*!< Read: error not present */
#define UARTE_ERRORSRC_OVERRUN_Present (1UL) /*!< Read: error present */
/* Register: UARTE_ENABLE */
/* Description: Enable UART */
/* Bits 3..0 : Enable or disable UARTE */
#define UARTE_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
#define UARTE_ENABLE_ENABLE_Msk (0xFUL << UARTE_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
#define UARTE_ENABLE_ENABLE_Disabled (0UL) /*!< Disable UARTE */
#define UARTE_ENABLE_ENABLE_Enabled (8UL) /*!< Enable UARTE */
/* Register: UARTE_PSEL_RTS */
/* Description: Pin select for RTS signal */
/* Bit 31 : Connection */
#define UARTE_PSEL_RTS_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */
#define UARTE_PSEL_RTS_CONNECT_Msk (0x1UL << UARTE_PSEL_RTS_CONNECT_Pos) /*!< Bit mask of CONNECT field. */
#define UARTE_PSEL_RTS_CONNECT_Connected (0UL) /*!< Connect */
#define UARTE_PSEL_RTS_CONNECT_Disconnected (1UL) /*!< Disconnect */
/* Bit 5 : Port number */
#define UARTE_PSEL_RTS_PORT_Pos (5UL) /*!< Position of PORT field. */
#define UARTE_PSEL_RTS_PORT_Msk (0x1UL << UARTE_PSEL_RTS_PORT_Pos) /*!< Bit mask of PORT field. */
/* Bits 4..0 : Pin number */
#define UARTE_PSEL_RTS_PIN_Pos (0UL) /*!< Position of PIN field. */
#define UARTE_PSEL_RTS_PIN_Msk (0x1FUL << UARTE_PSEL_RTS_PIN_Pos) /*!< Bit mask of PIN field. */
/* Register: UARTE_PSEL_TXD */
/* Description: Pin select for TXD signal */
/* Bit 31 : Connection */
#define UARTE_PSEL_TXD_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */
#define UARTE_PSEL_TXD_CONNECT_Msk (0x1UL << UARTE_PSEL_TXD_CONNECT_Pos) /*!< Bit mask of CONNECT field. */
#define UARTE_PSEL_TXD_CONNECT_Connected (0UL) /*!< Connect */
#define UARTE_PSEL_TXD_CONNECT_Disconnected (1UL) /*!< Disconnect */
/* Bit 5 : Port number */
#define UARTE_PSEL_TXD_PORT_Pos (5UL) /*!< Position of PORT field. */
#define UARTE_PSEL_TXD_PORT_Msk (0x1UL << UARTE_PSEL_TXD_PORT_Pos) /*!< Bit mask of PORT field. */
/* Bits 4..0 : Pin number */
#define UARTE_PSEL_TXD_PIN_Pos (0UL) /*!< Position of PIN field. */
#define UARTE_PSEL_TXD_PIN_Msk (0x1FUL << UARTE_PSEL_TXD_PIN_Pos) /*!< Bit mask of PIN field. */
/* Register: UARTE_PSEL_CTS */
/* Description: Pin select for CTS signal */
/* Bit 31 : Connection */
#define UARTE_PSEL_CTS_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */
#define UARTE_PSEL_CTS_CONNECT_Msk (0x1UL << UARTE_PSEL_CTS_CONNECT_Pos) /*!< Bit mask of CONNECT field. */
#define UARTE_PSEL_CTS_CONNECT_Connected (0UL) /*!< Connect */
#define UARTE_PSEL_CTS_CONNECT_Disconnected (1UL) /*!< Disconnect */
/* Bit 5 : Port number */
#define UARTE_PSEL_CTS_PORT_Pos (5UL) /*!< Position of PORT field. */
#define UARTE_PSEL_CTS_PORT_Msk (0x1UL << UARTE_PSEL_CTS_PORT_Pos) /*!< Bit mask of PORT field. */
/* Bits 4..0 : Pin number */
#define UARTE_PSEL_CTS_PIN_Pos (0UL) /*!< Position of PIN field. */
#define UARTE_PSEL_CTS_PIN_Msk (0x1FUL << UARTE_PSEL_CTS_PIN_Pos) /*!< Bit mask of PIN field. */
/* Register: UARTE_PSEL_RXD */
/* Description: Pin select for RXD signal */
/* Bit 31 : Connection */
#define UARTE_PSEL_RXD_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */
#define UARTE_PSEL_RXD_CONNECT_Msk (0x1UL << UARTE_PSEL_RXD_CONNECT_Pos) /*!< Bit mask of CONNECT field. */
#define UARTE_PSEL_RXD_CONNECT_Connected (0UL) /*!< Connect */
#define UARTE_PSEL_RXD_CONNECT_Disconnected (1UL) /*!< Disconnect */
/* Bit 5 : Port number */
#define UARTE_PSEL_RXD_PORT_Pos (5UL) /*!< Position of PORT field. */
#define UARTE_PSEL_RXD_PORT_Msk (0x1UL << UARTE_PSEL_RXD_PORT_Pos) /*!< Bit mask of PORT field. */
/* Bits 4..0 : Pin number */
#define UARTE_PSEL_RXD_PIN_Pos (0UL) /*!< Position of PIN field. */
#define UARTE_PSEL_RXD_PIN_Msk (0x1FUL << UARTE_PSEL_RXD_PIN_Pos) /*!< Bit mask of PIN field. */
/* Register: UARTE_BAUDRATE */
/* Description: Baud rate. Accuracy depends on the HFCLK source selected. */
/* Bits 31..0 : Baud rate */
#define UARTE_BAUDRATE_BAUDRATE_Pos (0UL) /*!< Position of BAUDRATE field. */
#define UARTE_BAUDRATE_BAUDRATE_Msk (0xFFFFFFFFUL << UARTE_BAUDRATE_BAUDRATE_Pos) /*!< Bit mask of BAUDRATE field. */
#define UARTE_BAUDRATE_BAUDRATE_Baud1200 (0x0004F000UL) /*!< 1200 baud (actual rate: 1205) */
#define UARTE_BAUDRATE_BAUDRATE_Baud2400 (0x0009D000UL) /*!< 2400 baud (actual rate: 2396) */
#define UARTE_BAUDRATE_BAUDRATE_Baud4800 (0x0013B000UL) /*!< 4800 baud (actual rate: 4808) */
#define UARTE_BAUDRATE_BAUDRATE_Baud9600 (0x00275000UL) /*!< 9600 baud (actual rate: 9598) */
#define UARTE_BAUDRATE_BAUDRATE_Baud14400 (0x003AF000UL) /*!< 14400 baud (actual rate: 14401) */
#define UARTE_BAUDRATE_BAUDRATE_Baud19200 (0x004EA000UL) /*!< 19200 baud (actual rate: 19208) */
#define UARTE_BAUDRATE_BAUDRATE_Baud28800 (0x0075C000UL) /*!< 28800 baud (actual rate: 28777) */
#define UARTE_BAUDRATE_BAUDRATE_Baud31250 (0x00800000UL) /*!< 31250 baud */
#define UARTE_BAUDRATE_BAUDRATE_Baud38400 (0x009D0000UL) /*!< 38400 baud (actual rate: 38369) */
#define UARTE_BAUDRATE_BAUDRATE_Baud56000 (0x00E50000UL) /*!< 56000 baud (actual rate: 55944) */
#define UARTE_BAUDRATE_BAUDRATE_Baud57600 (0x00EB0000UL) /*!< 57600 baud (actual rate: 57554) */
#define UARTE_BAUDRATE_BAUDRATE_Baud76800 (0x013A9000UL) /*!< 76800 baud (actual rate: 76923) */
#define UARTE_BAUDRATE_BAUDRATE_Baud115200 (0x01D60000UL) /*!< 115200 baud (actual rate: 115108) */
#define UARTE_BAUDRATE_BAUDRATE_Baud230400 (0x03B00000UL) /*!< 230400 baud (actual rate: 231884) */
#define UARTE_BAUDRATE_BAUDRATE_Baud250000 (0x04000000UL) /*!< 250000 baud */
#define UARTE_BAUDRATE_BAUDRATE_Baud460800 (0x07400000UL) /*!< 460800 baud (actual rate: 457143) */
#define UARTE_BAUDRATE_BAUDRATE_Baud921600 (0x0F000000UL) /*!< 921600 baud (actual rate: 941176) */
#define UARTE_BAUDRATE_BAUDRATE_Baud1M (0x10000000UL) /*!< 1 megabaud */
/* Register: UARTE_RXD_PTR */
/* Description: Data pointer */
/* Bits 31..0 : Data pointer */
#define UARTE_RXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */
#define UARTE_RXD_PTR_PTR_Msk (0xFFFFFFFFUL << UARTE_RXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */
/* Register: UARTE_RXD_MAXCNT */
/* Description: Maximum number of bytes in receive buffer */
/* Bits 15..0 : Maximum number of bytes in receive buffer */
#define UARTE_RXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */
#define UARTE_RXD_MAXCNT_MAXCNT_Msk (0xFFFFUL << UARTE_RXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */
/* Register: UARTE_RXD_AMOUNT */
/* Description: Number of bytes transferred in the last transaction */
/* Bits 15..0 : Number of bytes transferred in the last transaction */
#define UARTE_RXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */
#define UARTE_RXD_AMOUNT_AMOUNT_Msk (0xFFFFUL << UARTE_RXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */
/* Register: UARTE_TXD_PTR */
/* Description: Data pointer */
/* Bits 31..0 : Data pointer */
#define UARTE_TXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */
#define UARTE_TXD_PTR_PTR_Msk (0xFFFFFFFFUL << UARTE_TXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */
/* Register: UARTE_TXD_MAXCNT */
/* Description: Maximum number of bytes in transmit buffer */
/* Bits 15..0 : Maximum number of bytes in transmit buffer */
#define UARTE_TXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */
#define UARTE_TXD_MAXCNT_MAXCNT_Msk (0xFFFFUL << UARTE_TXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */
/* Register: UARTE_TXD_AMOUNT */
/* Description: Number of bytes transferred in the last transaction */
/* Bits 15..0 : Number of bytes transferred in the last transaction */
#define UARTE_TXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */
#define UARTE_TXD_AMOUNT_AMOUNT_Msk (0xFFFFUL << UARTE_TXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */
/* Register: UARTE_CONFIG */
/* Description: Configuration of parity and hardware flow control */
/* Bit 8 : Even or odd parity type */
#define UARTE_CONFIG_PARITYTYPE_Pos (8UL) /*!< Position of PARITYTYPE field. */
#define UARTE_CONFIG_PARITYTYPE_Msk (0x1UL << UARTE_CONFIG_PARITYTYPE_Pos) /*!< Bit mask of PARITYTYPE field. */
#define UARTE_CONFIG_PARITYTYPE_Even (0UL) /*!< Even parity */
#define UARTE_CONFIG_PARITYTYPE_Odd (1UL) /*!< Odd parity */
/* Bit 4 : Stop bits */
#define UARTE_CONFIG_STOP_Pos (4UL) /*!< Position of STOP field. */
#define UARTE_CONFIG_STOP_Msk (0x1UL << UARTE_CONFIG_STOP_Pos) /*!< Bit mask of STOP field. */
#define UARTE_CONFIG_STOP_One (0UL) /*!< One stop bit */
#define UARTE_CONFIG_STOP_Two (1UL) /*!< Two stop bits */
/* Bits 3..1 : Parity */
#define UARTE_CONFIG_PARITY_Pos (1UL) /*!< Position of PARITY field. */
#define UARTE_CONFIG_PARITY_Msk (0x7UL << UARTE_CONFIG_PARITY_Pos) /*!< Bit mask of PARITY field. */
#define UARTE_CONFIG_PARITY_Excluded (0x0UL) /*!< Exclude parity bit */
#define UARTE_CONFIG_PARITY_Included (0x7UL) /*!< Include even parity bit */
/* Bit 0 : Hardware flow control */
#define UARTE_CONFIG_HWFC_Pos (0UL) /*!< Position of HWFC field. */
#define UARTE_CONFIG_HWFC_Msk (0x1UL << UARTE_CONFIG_HWFC_Pos) /*!< Bit mask of HWFC field. */
#define UARTE_CONFIG_HWFC_Disabled (0UL) /*!< Disabled */
#define UARTE_CONFIG_HWFC_Enabled (1UL) /*!< Enabled */
/* =========================================================================================================================== */
/* ================ UICR ================ */
/* =========================================================================================================================== */

View File

@ -31,6 +31,7 @@
#include "NHW_CLOCK.h"
#include "NHW_RADIO.h"
#include "NHW_EGU.h"
#include "NHW_UART.h"
#include "bs_tracing.h"
#include "bs_oswrap.h"
#include "nsi_tasks.h"
@ -112,7 +113,22 @@ static const ppi_tasks_table_t ppi_tasks_table[]={ //just the ones we may use
{ (void*)&NRF_RADIO_regs.TASKS_EDSTOP, nhw_RADIO_TASK_EDSTOP},
{ (void*)&NRF_RADIO_regs.TASKS_CCASTART, nhw_RADIO_TASK_CCASTART},
{ (void*)&NRF_RADIO_regs.TASKS_CCASTOP, nhw_RADIO_TASK_CCASTOP},
//UART
{ (void*)&NRF_UARTE_regs[0].TASKS_STARTRX, nhw_uarte0_TASKS_STARTRX},
{ (void*)&NRF_UARTE_regs[0].TASKS_STOPRX, nhw_uarte0_TASKS_STOPRX},
{ (void*)&NRF_UARTE_regs[0].TASKS_STARTTX, nhw_uarte0_TASKS_STARTTX},
{ (void*)&NRF_UARTE_regs[0].TASKS_STOPTX, nhw_uarte0_TASKS_STOPTX},
{ (void*)&((NRF_UART_Type *)&NRF_UARTE_regs[0])->TASKS_SUSPEND, nhw_uarte0_TASKS_SUSPEND},
{ (void*)&NRF_UARTE_regs[0].TASKS_FLUSHRX, nhw_uarte0_TASKS_FLUSHRX},
{ (void*)&NRF_UARTE_regs[1].TASKS_STARTRX, nhw_uarte1_TASKS_STARTRX},
{ (void*)&NRF_UARTE_regs[1].TASKS_STOPRX, nhw_uarte1_TASKS_STOPRX},
{ (void*)&NRF_UARTE_regs[1].TASKS_STARTTX, nhw_uarte1_TASKS_STARTTX},
{ (void*)&NRF_UARTE_regs[1].TASKS_STOPTX, nhw_uarte1_TASKS_STOPTX},
{ (void*)&((NRF_UART_Type *)&NRF_UARTE_regs[1])->TASKS_SUSPEND, nhw_uarte1_TASKS_SUSPEND},
{ (void*)&NRF_UARTE_regs[1].TASKS_FLUSHRX, nhw_uarte1_TASKS_FLUSHRX},
//SPI0
//TWI0
//SPI1
@ -387,6 +403,18 @@ static const ppi_event_table_t ppi_events_table[] = { //better keep same order a
{RADIO_EVENTS_PHYEND, &NRF_RADIO_regs.EVENTS_PHYEND},
{RADIO_EVENTS_CTEPRESENT,&NRF_RADIO_regs.EVENTS_CTEPRESENT},
{UARTE0_EVENTS_CTS , &NRF_UARTE_regs[0].EVENTS_CTS },
{UARTE0_EVENTS_NCTS , &NRF_UARTE_regs[0].EVENTS_NCTS },
{UARTE0_EVENTS_RXDRDY , &NRF_UARTE_regs[0].EVENTS_RXDRDY },
{UARTE0_EVENTS_ENDRX , &NRF_UARTE_regs[0].EVENTS_ENDRX },
{UARTE0_EVENTS_TXDRDY , &NRF_UARTE_regs[0].EVENTS_TXDRDY },
{UARTE0_EVENTS_ENDTX , &NRF_UARTE_regs[0].EVENTS_ENDTX },
{UARTE0_EVENTS_ERROR , &NRF_UARTE_regs[0].EVENTS_ERROR },
{UARTE0_EVENTS_RXTO , &NRF_UARTE_regs[0].EVENTS_RXTO },
{UARTE0_EVENTS_RXSTARTED, &NRF_UARTE_regs[0].EVENTS_RXSTARTED},
{UARTE0_EVENTS_TXSTARTED, &NRF_UARTE_regs[0].EVENTS_TXSTARTED},
{UARTE0_EVENTS_TXSTOPPED, &NRF_UARTE_regs[0].EVENTS_TXSTOPPED},
{GPIOTE_EVENTS_IN_0, &NRF_GPIOTE_regs.EVENTS_IN[0]},
{GPIOTE_EVENTS_IN_1, &NRF_GPIOTE_regs.EVENTS_IN[1]},
{GPIOTE_EVENTS_IN_2, &NRF_GPIOTE_regs.EVENTS_IN[2]},
@ -555,6 +583,18 @@ static const ppi_event_table_t ppi_events_table[] = { //better keep same order a
{RTC2_EVENTS_COMPARE_2, &NRF_RTC_regs[2].EVENTS_COMPARE[2]},
{RTC2_EVENTS_COMPARE_3, &NRF_RTC_regs[2].EVENTS_COMPARE[3]},
{UARTE1_EVENTS_CTS , &NRF_UARTE_regs[1].EVENTS_CTS },
{UARTE1_EVENTS_NCTS , &NRF_UARTE_regs[1].EVENTS_NCTS },
{UARTE1_EVENTS_RXDRDY , &NRF_UARTE_regs[1].EVENTS_RXDRDY },
{UARTE1_EVENTS_ENDRX , &NRF_UARTE_regs[1].EVENTS_ENDRX },
{UARTE1_EVENTS_TXDRDY , &NRF_UARTE_regs[1].EVENTS_TXDRDY },
{UARTE1_EVENTS_ENDTX , &NRF_UARTE_regs[1].EVENTS_ENDTX },
{UARTE1_EVENTS_ERROR , &NRF_UARTE_regs[1].EVENTS_ERROR },
{UARTE1_EVENTS_RXTO , &NRF_UARTE_regs[1].EVENTS_RXTO },
{UARTE1_EVENTS_RXSTARTED, &NRF_UARTE_regs[1].EVENTS_RXSTARTED},
{UARTE1_EVENTS_TXSTARTED, &NRF_UARTE_regs[1].EVENTS_TXSTARTED},
{UARTE1_EVENTS_TXSTOPPED, &NRF_UARTE_regs[1].EVENTS_TXSTOPPED},
{NUMBER_PPI_EVENTS, NULL} //End marker
};

View File

@ -59,6 +59,18 @@ typedef enum { //Note that, for performance, it is better to leave commented the
// 2 0x40002000 UARTE
// 2 0x40002000 UART
UARTE0_EVENTS_CTS,
UARTE0_EVENTS_NCTS ,
UARTE0_EVENTS_RXDRDY ,
UARTE0_EVENTS_ENDRX ,
UARTE0_EVENTS_TXDRDY ,
UARTE0_EVENTS_ENDTX ,
UARTE0_EVENTS_ERROR ,
UARTE0_EVENTS_RXTO ,
UARTE0_EVENTS_RXSTARTED ,
UARTE0_EVENTS_TXSTARTED ,
UARTE0_EVENTS_TXSTOPPED ,
// 3 0x40003000 TWIM
// 3 0x40003000 SPIS
// 3 0x40003000 SPIM
@ -306,6 +318,18 @@ typedef enum { //Note that, for performance, it is better to leave commented the
// 38 0x40026000 FPU
// 39 0x40027000 USBD
// 40 0x40028000 UARTE
UARTE1_EVENTS_CTS,
UARTE1_EVENTS_NCTS ,
UARTE1_EVENTS_RXDRDY ,
UARTE1_EVENTS_ENDRX ,
UARTE1_EVENTS_TXDRDY ,
UARTE1_EVENTS_ENDTX ,
UARTE1_EVENTS_ERROR ,
UARTE1_EVENTS_RXTO ,
UARTE1_EVENTS_RXSTARTED ,
UARTE1_EVENTS_TXSTARTED ,
UARTE1_EVENTS_TXSTOPPED ,
// 41 0x40029000 QSPI
// 45 0x4002D000 PWM
// 47 0x4002F000 SPIM

127
src/nrfx/hal/nrf_uart.c Normal file
View File

@ -0,0 +1,127 @@
/*
* Copyright (c) 2023, Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*
* Note that the function prototypes are taken from the NRFx HAL
*/
#include <stdint.h>
#include "hal/nrf_uart.h"
#include "bs_tracing.h"
#include "NHW_UART.h"
static int uart_number_from_ptr(NRF_UART_Type * p_reg){
int i = ( (int)p_reg - (int)NRF_UARTE_regs ) / sizeof(NRF_UARTE_Type);
return i;
}
void nrf_uart_task_trigger(NRF_UART_Type * p_reg, nrf_uart_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
int i = uart_number_from_ptr(p_reg);
#define CASE_TASK(x) \
case NRF_UART_TASK_##x: nhw_UARTE_regw_sideeffects_TASKS_##x(i); break
switch (task) {
CASE_TASK(STARTRX);
CASE_TASK(STOPRX);
CASE_TASK(STARTTX);
CASE_TASK(STOPTX);
CASE_TASK(SUSPEND);
default:
bs_trace_error_line_time("Not supported task started in nrf_clock, %d\n", task);
break;
}
#undef CASE_TASK
}
void nrf_uart_int_enable(NRF_UART_Type * p_reg, uint32_t mask)
{
int i = uart_number_from_ptr(p_reg);
p_reg->INTENSET = mask;
nhw_UARTE_regw_sideeffects_INTENSET(i);
}
void nrf_uart_int_disable(NRF_UART_Type * p_reg, uint32_t mask)
{
int i = uart_number_from_ptr(p_reg);
p_reg->INTENCLR = mask;
nhw_UARTE_regw_sideeffects_INTENCLR(i);
}
void nrf_uart_event_clear(NRF_UART_Type * p_reg, nrf_uart_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
int i = uart_number_from_ptr(p_reg);
nhw_UARTE_regw_sideeffects_EVENTS_all(i);
}
uint32_t nrf_uart_errorsrc_get_and_clear(NRF_UART_Type * p_reg)
{
int i = uart_number_from_ptr(p_reg);
return nhw_UARTE_regr_sideeffects_ERRORSRC(i);
}
uint8_t nrf_uart_rxd_get(NRF_UART_Type const * p_reg)
{
int i = uart_number_from_ptr((NRF_UART_Type *)p_reg);
return nhw_UARTE_regr_sideeffects_RXD(i);
}
void nrf_uart_txd_set(NRF_UART_Type * p_reg, uint8_t txd)
{
p_reg->TXD = txd;
int i = uart_number_from_ptr(p_reg);
nhw_UARTE_regw_sideeffects_TXD(i);
}
void nrf_uart_disable(NRF_UART_Type * p_reg)
{
int i = uart_number_from_ptr(p_reg);
p_reg->ENABLE = UART_ENABLE_ENABLE_Disabled;
nhw_UARTE_regw_sideeffects_ENABLE(i);
}
#if defined(DPPI_PRESENT)
static void nrf_uart_subscribe_common(NRF_UART_Type * p_reg,
nrf_uart_task_t task)
{
int i = uart_number_from_ptr(p_reg);
#define CASE_TASK(TASKN) \
case NRF_UART_TASK_##TASKN: nhw_uart_regw_sideeffects_SUBSCRIBE_##TASKN(i); break;
switch (task) {
CASE_TASK(STARTRX);
CASE_TASK(STOPRX);
CASE_TASK(STARTTX);
CASE_TASK(STOPTX);
CASE_TASK(SUSPEND);
default:
bs_trace_error_line_time("Attempted to subscribe to a not-supported task in the nrf_uart(%i)\n",
task);
break;
}
#undef CASE_TASK
}
void nrf_uart_subscribe_set(NRF_UART_Type * p_reg,
nrf_uart_task_t task,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
nrf_uart_subscribe_common(p_reg, task);
}
void nrf_uart_subscribe_clear(NRF_UART_Type * p_reg,
nrf_uart_task_t task)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
nrf_uart_subscribe_common(p_reg, task);
}
#endif /* defined(DPPI_PRESENT) */

114
src/nrfx/hal/nrf_uarte.c Normal file
View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2023, Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*
* Note that the function prototypes are taken from the NRFx HAL
*/
#include <stdint.h>
#include "hal/nrf_uarte.h"
#include "bs_tracing.h"
#include "NHW_UART.h"
static int uarte_number_from_ptr(NRF_UARTE_Type * p_reg){
int i = ( (int)p_reg - (int)NRF_UARTE_regs ) / sizeof(NRF_UARTE_Type);
return i;
}
void nrf_uarte_task_trigger(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
int i = uarte_number_from_ptr(p_reg);
#define CASE_TASK(x) \
case NRF_UARTE_TASK_##x: nhw_UARTE_regw_sideeffects_TASKS_##x(i); break
switch (task) {
CASE_TASK(STARTRX);
CASE_TASK(STOPRX);
CASE_TASK(STARTTX);
CASE_TASK(STOPTX);
CASE_TASK(FLUSHRX);
default:
bs_trace_error_line_time("Not supported task started in nrf_clock, %d\n", task);
break;
}
#undef CASE_TASK
}
void nrf_uarte_int_enable(NRF_UARTE_Type * p_reg, uint32_t mask)
{
int i = uarte_number_from_ptr(p_reg);
p_reg->INTENSET = mask;
nhw_UARTE_regw_sideeffects_INTENSET(i);
}
void nrf_uarte_int_disable(NRF_UARTE_Type * p_reg, uint32_t mask)
{
int i = uarte_number_from_ptr(p_reg);
p_reg->INTENCLR = mask;
nhw_UARTE_regw_sideeffects_INTENCLR(i);
}
void nrf_uarte_event_clear(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
int i = uarte_number_from_ptr(p_reg);
nhw_UARTE_regw_sideeffects_EVENTS_all(i);
}
uint32_t nrf_uarte_errorsrc_get_and_clear(NRF_UARTE_Type * p_reg)
{
int i = uarte_number_from_ptr(p_reg);
return nhw_UARTE_regr_sideeffects_ERRORSRC(i);
}
void nrf_uarte_disable(NRF_UARTE_Type * p_reg)
{
int i = uarte_number_from_ptr(p_reg);
p_reg->ENABLE = UARTE_ENABLE_ENABLE_Disabled;
nhw_UARTE_regw_sideeffects_ENABLE(i);
}
#if defined(DPPI_PRESENT)
static void nrf_uarte_subscribe_common(NRF_UARTE_Type * p_reg,
nrf_uarte_task_t task)
{
int i = uarte_number_from_ptr(p_reg);
#define CASE_TASK(TASKN) \
case NRF_UARTE_TASK_##TASKN: nhw_UARTE_regw_sideeffects_SUBSCRIBE_##TASKN(i); break;
switch (task) {
CASE_TASK(STARTRX);
CASE_TASK(STOPRX);
CASE_TASK(STARTTX);
CASE_TASK(STOPTX);
CASE_TASK(FLUSHRX);
default:
bs_trace_error_line_time("Attempted to subscribe to a not-supported task in the nrf_uart(%i)\n",
task);
break;
}
#undef CASE_TASK
}
void nrf_uarte_subscribe_set(NRF_UARTE_Type * p_reg,
nrf_uarte_task_t task,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
nrf_uarte_subscribe_common(p_reg, task);
}
void nrf_uarte_subscribe_clear(NRF_UARTE_Type * p_reg,
nrf_uarte_task_t task)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
nrf_uarte_subscribe_common(p_reg, task);
}
#endif /* defined(DPPI_PRESENT) */

View File

@ -95,6 +95,13 @@ extern NRF_EGU_Type NRF_EGU_regs[6];
#undef NRF_UICR_BASE
extern NRF_UICR_Type *NRF_UICR_regs_p[];
#define NRF_UICR_BASE (NRF_UICR_regs_p[0])
extern NRF_UARTE_Type NRF_UARTE_regs[];
#undef NRF_UART0_BASE
#define NRF_UART0_BASE (&NRF_UARTE_regs[NHW_UART_0])
#undef NRF_UARTE0_BASE
#define NRF_UARTE0_BASE (&NRF_UARTE_regs[NHW_UART_0])
#undef NRF_UARTE1_BASE
#define NRF_UARTE1_BASE (&NRF_UARTE_regs[NHW_UART_1])
/********************************************************************/
/********************************************************************/
@ -166,8 +173,9 @@ extern NRF_IPC_Type NRF_IPC_regs[NHW_IPC_TOTAL_INST];
#define NRF_TWIM0_NS_BASE NULL
#undef NRF_TWIS0_NS_BASE
#define NRF_TWIS0_NS_BASE NULL
extern NRF_UARTE_Type NRF_UARTE_regs[];
#undef NRF_UARTE0_NS_BASE
#define NRF_UARTE0_NS_BASE NULL
#define NRF_UARTE0_NS_BASE (&NRF_UARTE_regs[NHW_UARTE_NET0])
extern NRF_EGU_Type NRF_EGU_regs[];
#undef NRF_EGU0_NS_BASE
#define NRF_EGU0_NS_BASE (&NRF_EGU_regs[NHW_EGU_NET0])
@ -270,8 +278,9 @@ extern NRF_RESET_Type *NRF_RESET_regs[];
#define NRF_TWIM0_NS_BASE NULL
#undef NRF_TWIS0_NS_BASE
#define NRF_TWIS0_NS_BASE NULL
extern NRF_UARTE_Type NRF_UARTE_regs[];
#undef NRF_UARTE0_NS_BASE
#define NRF_UARTE0_NS_BASE NULL
#define NRF_UARTE0_NS_BASE (&NRF_UARTE_regs[NHW_UARTE_APP0])
#undef NRF_SPIM0_S_BASE
#define NRF_SPIM0_S_BASE NULL
#undef NRF_SPIS0_S_BASE
@ -281,7 +290,7 @@ extern NRF_RESET_Type *NRF_RESET_regs[];
#undef NRF_TWIS0_S_BASE
#define NRF_TWIS0_S_BASE NULL
#undef NRF_UARTE0_S_BASE
#define NRF_UARTE0_S_BASE NULL
#define NRF_UARTE0_S_BASE (&NRF_UARTE_regs[NHW_UARTE_APP0])
#undef NRF_SPIM1_NS_BASE
#define NRF_SPIM1_NS_BASE NULL
#undef NRF_SPIS1_NS_BASE
@ -291,7 +300,7 @@ extern NRF_RESET_Type *NRF_RESET_regs[];
#undef NRF_TWIS1_NS_BASE
#define NRF_TWIS1_NS_BASE NULL
#undef NRF_UARTE1_NS_BASE
#define NRF_UARTE1_NS_BASE NULL
#define NRF_UARTE1_NS_BASE (&NRF_UARTE_regs[NHW_UARTE_APP1])
#undef NRF_SPIM1_S_BASE
#define NRF_SPIM1_S_BASE NULL
#undef NRF_SPIS1_S_BASE
@ -301,7 +310,7 @@ extern NRF_RESET_Type *NRF_RESET_regs[];
#undef NRF_TWIS1_S_BASE
#define NRF_TWIS1_S_BASE NULL
#undef NRF_UARTE1_S_BASE
#define NRF_UARTE1_S_BASE NULL
#define NRF_UARTE1_S_BASE (&NRF_UARTE_regs[NHW_UARTE_APP1])
#undef NRF_SPIM4_NS_BASE
#define NRF_SPIM4_NS_BASE NULL
#undef NRF_SPIM4_S_BASE
@ -315,7 +324,7 @@ extern NRF_RESET_Type *NRF_RESET_regs[];
#undef NRF_TWIS2_NS_BASE
#define NRF_TWIS2_NS_BASE NULL
#undef NRF_UARTE2_NS_BASE
#define NRF_UARTE2_NS_BASE NULL
#define NRF_UARTE2_NS_BASE (&NRF_UARTE_regs[NHW_UARTE_APP2])
#undef NRF_SPIM2_S_BASE
#define NRF_SPIM2_S_BASE NULL
#undef NRF_SPIS2_S_BASE
@ -325,7 +334,7 @@ extern NRF_RESET_Type *NRF_RESET_regs[];
#undef NRF_TWIS2_S_BASE
#define NRF_TWIS2_S_BASE NULL
#undef NRF_UARTE2_S_BASE
#define NRF_UARTE2_S_BASE NULL
#define NRF_UARTE2_S_BASE (&NRF_UARTE_regs[NHW_UARTE_APP2])
#undef NRF_SPIM3_NS_BASE
#define NRF_SPIM3_NS_BASE NULL
#undef NRF_SPIS3_NS_BASE
@ -335,7 +344,7 @@ extern NRF_RESET_Type *NRF_RESET_regs[];
#undef NRF_TWIS3_NS_BASE
#define NRF_TWIS3_NS_BASE NULL
#undef NRF_UARTE3_NS_BASE
#define NRF_UARTE3_NS_BASE NULL
#define NRF_UARTE3_NS_BASE (&NRF_UARTE_regs[NHW_UARTE_APP3])
#undef NRF_SPIM3_S_BASE
#define NRF_SPIM3_S_BASE NULL
#undef NRF_SPIS3_S_BASE
@ -345,7 +354,7 @@ extern NRF_RESET_Type *NRF_RESET_regs[];
#undef NRF_TWIS3_S_BASE
#define NRF_TWIS3_S_BASE NULL
#undef NRF_UARTE3_S_BASE
#define NRF_UARTE3_S_BASE NULL
#define NRF_UARTE3_S_BASE (&NRF_UARTE_regs[NHW_UARTE_APP3])
#undef NRF_GPIOTE0_S_BASE
#define NRF_GPIOTE0_S_BASE NULL
#undef NRF_SAADC_NS_BASE