UART(E): Update RTS pin level as soon as the configuration is changed

* Update RTS pin level as soon as the configuration is changed,
  either when the UART is enabled or CONFIG is changed.
* The FIFO backend will start, at boot, preassuming the CTS is raised
  until it hears otherwise from the other side.
  (The UART model comes out of boot with RTS high)

Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
This commit is contained in:
Alberto Escolar Piedras 2024-01-09 15:05:42 +01:00
parent b39e4489f5
commit bc648f255d
5 changed files with 70 additions and 12 deletions

View File

@ -416,16 +416,20 @@ static bool flow_control_on(uint inst) {
return (NRF_UART_regs[inst]->CONFIG & UART_CONFIG_HWFC_Msk) != 0;
}
static void propagate_RTS_R(uint inst, struct uarte_status *u_el) {
if (flow_control_on(inst)) {
if (u_el->backend.RTS_pin_toggle_f) {
u_el->backend.RTS_pin_toggle_f(inst, u_el->RTSR);
}
}
}
static void lower_RTS_R(uint inst, struct uarte_status *u_el) {
if (u_el->RTSR == false) {
return;
}
u_el->RTSR = false;
if (flow_control_on(inst)) {
if (u_el->backend.RTS_pin_toggle_f) {
u_el->backend.RTS_pin_toggle_f(inst, false);
}
}
propagate_RTS_R(inst, u_el);
}
static void raise_RTS_R(uint inst, struct uarte_status *u_el) {
@ -433,11 +437,7 @@ static void raise_RTS_R(uint inst, struct uarte_status *u_el) {
return;
}
u_el->RTSR = true;
if (flow_control_on(inst)) {
if (u_el->backend.RTS_pin_toggle_f) {
u_el->backend.RTS_pin_toggle_f(inst, true);
}
}
propagate_RTS_R(inst, u_el);
}
static void notify_backend_RxOnOff(uint inst, struct uarte_status *u_el, bool OnNotOff) {
@ -519,6 +519,10 @@ void nhw_UARTE_CTS_raised(uint inst) {
return;
}
nhw_uarte_st[inst].CTS_blocking = true;
if ( !(uart_enabled(inst) || uarte_enabled(inst)) ) {
return;
}
nhw_UARTE_signal_EVENTS_NCTS(inst);
}
@ -845,12 +849,13 @@ void nhw_UARTE_TASK_SUSPEND(int inst) {
}
void nhw_UARTE_regw_sideeffects_ENABLE(unsigned int inst) {
struct uarte_status * u_el = &nhw_uarte_st[inst];
if (NRF_UARTE_regs[inst].ENABLE != 0) {
propagate_RTS_R(inst, u_el);
return;
}
struct uarte_status * u_el = &nhw_uarte_st[inst];
if (u_el->tx_status != Tx_Off) {
bs_trace_warning_time_line("UART%i disabled while Tx was not Off (%i)\n", inst, u_el->tx_status);
}
@ -887,6 +892,13 @@ void nhw_UARTE_regw_sideeffects_ENABLE(unsigned int inst) {
notify_backend_RxOnOff(inst, u_el, false);
}
void nhw_UARTE_regw_sideeffects_CONFIG(unsigned int inst) {
if (NRF_UARTE_regs[inst].ENABLE != 0) {
struct uarte_status *u_el = &nhw_uarte_st[inst];
propagate_RTS_R(inst, u_el);
}
}
uint32_t nhw_UARTE_regr_sideeffects_ERRORSRC(unsigned int inst) {
uint32_t value = NRF_UARTE_regs[inst].ERRORSRC;
NRF_UARTE_regs[inst].ERRORSRC = 0;

View File

@ -40,6 +40,7 @@ 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);
void nhw_UARTE_regw_sideeffects_CONFIG(unsigned int inst);
#if (NHW_HAS_PPI)
void nhw_uarte0_TASKS_STARTRX(void);

View File

@ -144,6 +144,7 @@ static void nhw_ufifo_backend_init(void) {
st.uart_enable_notify_f = nhw_ufifo_enable_notify;
nhw_UARTE_backend_register(i, &st);
nhw_UARTE_CTS_raised(i);
u_el->Tx_timer = 0;
u_el->Rx_timer = uf_mdt;

View File

@ -85,6 +85,28 @@ void nrf_uart_disable(NRF_UART_Type * p_reg)
nhw_UARTE_regw_sideeffects_ENABLE(i);
}
void nrf_uart_enable(NRF_UART_Type * p_reg)
{
int i = uart_number_from_ptr(p_reg);
p_reg->ENABLE = UART_ENABLE_ENABLE_Enabled;
nhw_UARTE_regw_sideeffects_ENABLE(i);
}
void nrf_uart_configure(NRF_UART_Type * p_reg,
nrf_uart_config_t const * p_cfg)
{
int i = uart_number_from_ptr(p_reg);
p_reg->CONFIG = (uint32_t)p_cfg->parity
#if defined(UART_CONFIG_STOP_Msk)
| (uint32_t)p_cfg->stop
#endif
#if defined(UART_CONFIG_PARITYTYPE_Msk)
| (uint32_t)p_cfg->paritytype
#endif
| (uint32_t)p_cfg->hwfc;
nhw_UARTE_regw_sideeffects_CONFIG(i);
}
#if defined(DPPI_PRESENT)
static void nrf_uart_subscribe_common(NRF_UART_Type * p_reg,

View File

@ -65,6 +65,13 @@ uint32_t nrf_uarte_errorsrc_get_and_clear(NRF_UARTE_Type * p_reg)
return nhw_UARTE_regr_sideeffects_ERRORSRC(i);
}
void nrf_uarte_enable(NRF_UARTE_Type * p_reg)
{
int i = uarte_number_from_ptr(p_reg);
p_reg->ENABLE = UARTE_ENABLE_ENABLE_Enabled;
nhw_UARTE_regw_sideeffects_ENABLE(i);
}
void nrf_uarte_disable(NRF_UARTE_Type * p_reg)
{
int i = uarte_number_from_ptr(p_reg);
@ -72,6 +79,21 @@ void nrf_uarte_disable(NRF_UARTE_Type * p_reg)
nhw_UARTE_regw_sideeffects_ENABLE(i);
}
void nrf_uarte_configure(NRF_UARTE_Type * p_reg,
nrf_uarte_config_t const * p_cfg)
{
int i = uarte_number_from_ptr(p_reg);
p_reg->CONFIG = (uint32_t)p_cfg->parity
#if defined(UARTE_CONFIG_STOP_Msk)
| (uint32_t)p_cfg->stop
#endif
#if defined(UARTE_CONFIG_PARITYTYPE_Msk)
| (uint32_t)p_cfg->paritytype
#endif
| (uint32_t)p_cfg->hwfc;
nhw_UARTE_regw_sideeffects_CONFIG(i);
}
#if defined(DPPI_PRESENT)
static void nrf_uarte_subscribe_common(NRF_UARTE_Type * p_reg,