diff --git a/targets/TARGET_NUVOTON/TARGET_M2351/serial_api.c b/targets/TARGET_NUVOTON/TARGET_M2351/serial_api.c index d6ad1afdda..254a23fd43 100644 --- a/targets/TARGET_NUVOTON/TARGET_M2351/serial_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M2351/serial_api.c @@ -361,10 +361,7 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi { UART_T *uart_base = (UART_T *) NU_MODBASE(obj->serial.uart); - // First, disable flow control completely. - uart_base->INTEN &= ~(UART_INTEN_ATORTSEN_Msk | UART_INTEN_ATOCTSEN_Msk); - - if ((type == FlowControlRTS || type == FlowControlRTSCTS) && rxflow != NC) { + if (rxflow != NC) { // Check if RTS pin matches. uint32_t uart_rts = pinmap_peripheral(rxflow, PinMap_UART_RTS); MBED_ASSERT(uart_rts == obj->serial.uart); @@ -378,14 +375,24 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi uart_base->MODEM |= UART_MODEM_RTSACTLV_Msk; // NOTE: Added in M480/M2351. After configuring RTSACTLV, re-enable TX/RX. uart_base->FUNCSEL &= ~UART_FUNCSEL_TXRXDIS_Msk; - + // Configure RTS trigger level to 8 bytes uart_base->FIFO = (uart_base->FIFO & ~UART_FIFO_RTSTRGLV_Msk) | UART_FIFO_RTSTRGLV_8BYTES; - - // Enable RTS - uart_base->INTEN |= UART_INTEN_ATORTSEN_Msk; + + if (type == FlowControlRTS || type == FlowControlRTSCTS) { + // Enable RTS + uart_base->INTEN |= UART_INTEN_ATORTSEN_Msk; + } else { + // Disable RTS + uart_base->INTEN &= ~UART_INTEN_ATORTSEN_Msk; + /* Drive nRTS pin output to low-active. Allow the peer to be able to send data + * even though its CTS is still enabled. */ + uart_base->MODEM &= ~UART_MODEM_RTS_Msk; + } } - if ((type == FlowControlCTS || type == FlowControlRTSCTS) && txflow != NC) { + /* If CTS is disabled, we don't need to configure CTS. But to be consistent with + * RTS code above, we still configure CTS. */ + if (txflow != NC) { // Check if CTS pin matches. uint32_t uart_cts = pinmap_peripheral(txflow, PinMap_UART_CTS); MBED_ASSERT(uart_cts == obj->serial.uart); @@ -400,8 +407,13 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi // NOTE: Added in M480/M2351. After configuring CTSACTLV, re-enable TX/RX. uart_base->FUNCSEL &= ~UART_FUNCSEL_TXRXDIS_Msk; - // Enable CTS - uart_base->INTEN |= UART_INTEN_ATOCTSEN_Msk; + if (type == FlowControlCTS || type == FlowControlRTSCTS) { + // Enable CTS + uart_base->INTEN |= UART_INTEN_ATOCTSEN_Msk; + } else { + // Disable CTS + uart_base->INTEN &= ~UART_INTEN_ATOCTSEN_Msk; + } } } diff --git a/targets/TARGET_NUVOTON/TARGET_M451/serial_api.c b/targets/TARGET_NUVOTON/TARGET_M451/serial_api.c index ec557a43e6..b2ebd75340 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/serial_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/serial_api.c @@ -313,11 +313,8 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) { UART_T *uart_base = (UART_T *) NU_MODBASE(obj->serial.uart); - - // First, disable flow control completely. - uart_base->INTEN &= ~(UART_INTEN_ATORTSEN_Msk | UART_INTEN_ATOCTSEN_Msk); - if ((type == FlowControlRTS || type == FlowControlRTSCTS) && rxflow != NC) { + if (rxflow != NC) { // Check if RTS pin matches. uint32_t uart_rts = pinmap_peripheral(rxflow, PinMap_UART_RTS); MBED_ASSERT(uart_rts == obj->serial.uart); @@ -325,12 +322,24 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi pinmap_pinout(rxflow, PinMap_UART_RTS); // nRTS pin output is low level active uart_base->MODEM |= UART_MODEM_RTSACTLV_Msk; + // Configure RTS trigger level to 8 bytes uart_base->FIFO = (uart_base->FIFO & ~UART_FIFO_RTSTRGLV_Msk) | UART_FIFO_RTSTRGLV_8BYTES; - // Enable RTS - uart_base->INTEN |= UART_INTEN_ATORTSEN_Msk; + + if (type == FlowControlRTS || type == FlowControlRTSCTS) { + // Enable RTS + uart_base->INTEN |= UART_INTEN_ATORTSEN_Msk; + } else { + // Disable RTS + uart_base->INTEN &= ~UART_INTEN_ATORTSEN_Msk; + /* Drive nRTS pin output to low-active. Allow the peer to be able to send data + * even though its CTS is still enabled. */ + uart_base->MODEM &= ~UART_MODEM_RTS_Msk; + } } - - if ((type == FlowControlCTS || type == FlowControlRTSCTS) && txflow != NC) { + + /* If CTS is disabled, we don't need to configure CTS. But to be consistent with + * RTS code above, we still configure CTS. */ + if (txflow != NC) { // Check if CTS pin matches. uint32_t uart_cts = pinmap_peripheral(txflow, PinMap_UART_CTS); MBED_ASSERT(uart_cts == obj->serial.uart); @@ -338,8 +347,14 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi pinmap_pinout(txflow, PinMap_UART_CTS); // nCTS pin input is low level active uart_base->MODEMSTS |= UART_MODEMSTS_CTSACTLV_Msk; - // Enable CTS - uart_base->INTEN |= UART_INTEN_ATOCTSEN_Msk; + + if (type == FlowControlCTS || type == FlowControlRTSCTS) { + // Enable CTS + uart_base->INTEN |= UART_INTEN_ATOCTSEN_Msk; + } else { + // Disable CTS + uart_base->INTEN &= ~UART_INTEN_ATOCTSEN_Msk; + } } } diff --git a/targets/TARGET_NUVOTON/TARGET_M480/serial_api.c b/targets/TARGET_NUVOTON/TARGET_M480/serial_api.c index 356ebcb599..1eff862a60 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/serial_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/serial_api.c @@ -348,16 +348,13 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi { UART_T *uart_base = (UART_T *) NU_MODBASE(obj->serial.uart); - // First, disable flow control completely. - uart_base->INTEN &= ~(UART_INTEN_ATORTSEN_Msk | UART_INTEN_ATOCTSEN_Msk); - - if ((type == FlowControlRTS || type == FlowControlRTSCTS) && rxflow != NC) { + if (rxflow != NC) { // Check if RTS pin matches. uint32_t uart_rts = pinmap_peripheral(rxflow, PinMap_UART_RTS); MBED_ASSERT(uart_rts == obj->serial.uart); // Enable the pin for RTS function pinmap_pinout(rxflow, PinMap_UART_RTS); - + // NOTE: Added in M480. Before configuring RTSACTLV, disable TX/RX. uart_base->FUNCSEL |= UART_FUNCSEL_TXRXDIS_Msk; while (uart_base->FIFOSTS & UART_FIFOSTS_TXRXACT_Msk); @@ -365,14 +362,24 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi uart_base->MODEM |= UART_MODEM_RTSACTLV_Msk; // NOTE: Added in M480. After configuring RTSACTLV, re-enable TX/RX. uart_base->FUNCSEL &= ~UART_FUNCSEL_TXRXDIS_Msk; - + // Configure RTS trigger level to 8 bytes uart_base->FIFO = (uart_base->FIFO & ~UART_FIFO_RTSTRGLV_Msk) | UART_FIFO_RTSTRGLV_8BYTES; - // Enable RTS - uart_base->INTEN |= UART_INTEN_ATORTSEN_Msk; + if (type == FlowControlRTS || type == FlowControlRTSCTS) { + // Enable RTS + uart_base->INTEN |= UART_INTEN_ATORTSEN_Msk; + } else { + // Disable RTS + uart_base->INTEN &= ~UART_INTEN_ATORTSEN_Msk; + /* Drive nRTS pin output to low-active. Allow the peer to be able to send data + * even though its CTS is still enabled. */ + uart_base->MODEM &= ~UART_MODEM_RTS_Msk; + } } - if ((type == FlowControlCTS || type == FlowControlRTSCTS) && txflow != NC) { + /* If CTS is disabled, we don't need to configure CTS. But to be consistent with + * RTS code above, we still configure CTS. */ + if (txflow != NC) { // Check if CTS pin matches. uint32_t uart_cts = pinmap_peripheral(txflow, PinMap_UART_CTS); MBED_ASSERT(uart_cts == obj->serial.uart); @@ -387,8 +394,13 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi // NOTE: Added in M480. After configuring CTSACTLV, re-enable TX/RX. uart_base->FUNCSEL &= ~UART_FUNCSEL_TXRXDIS_Msk; - // Enable CTS - uart_base->INTEN |= UART_INTEN_ATOCTSEN_Msk; + if (type == FlowControlCTS || type == FlowControlRTSCTS) { + // Enable CTS + uart_base->INTEN |= UART_INTEN_ATOCTSEN_Msk; + } else { + // Disable CTS + uart_base->INTEN &= ~UART_INTEN_ATOCTSEN_Msk; + } } } diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/serial_api.c b/targets/TARGET_NUVOTON/TARGET_NANO100/serial_api.c index 447d8fb5d8..3f5572a0ff 100644 --- a/targets/TARGET_NUVOTON/TARGET_NANO100/serial_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NANO100/serial_api.c @@ -274,11 +274,8 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) { UART_T *uart_base = (UART_T *) NU_MODBASE(obj->serial.uart); - - // First, disable flow control completely. - UART_DisableFlowCtrl(uart_base); - if ((type == FlowControlRTS || type == FlowControlRTSCTS) && rxflow != NC) { + if (rxflow != NC) { // Check if RTS pin matches. uint32_t uart_rts = pinmap_peripheral(rxflow, PinMap_UART_RTS); MBED_ASSERT(uart_rts == obj->serial.uart); @@ -286,15 +283,26 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi pinmap_pinout(rxflow, PinMap_UART_RTS); // nRTS pin output is low level active uart_base->MCSR |= UART_MCSR_LEV_RTS_Msk; - // Set RTS Trigger Level as 8 bytes + // Configure RTS trigger level to 8 bytes uart_base->TLCTL = (uart_base->TLCTL & ~UART_TLCTL_RTS_TRI_LEV_Msk) | UART_TLCTL_RTS_TRI_LEV_8BYTES; - // Set RX Trigger Level as 8 bytes + // Configure RX Trigger Level to 8 bytes uart_base->TLCTL = (uart_base->TLCTL & ~UART_TLCTL_RFITL_Msk) | UART_TLCTL_RFITL_8BYTES; - // Enable RTS - uart_base->CTL |= UART_CTL_AUTO_RTS_EN_Msk; + + if (type == FlowControlRTS || type == FlowControlRTSCTS) { + // Enable RTS + uart_base->CTL |= UART_CTL_AUTO_RTS_EN_Msk; + } else { + // Disable RTS + uart_base->CTL &= ~UART_CTL_AUTO_RTS_EN_Msk; + /* Drive nRTS pin output to low-active. Allow the peer to be able to send data + * even though its CTS is still enabled. */ + /* NOTE: NOT SUPPORT on NANO130 */ + } } - - if ((type == FlowControlCTS || type == FlowControlRTSCTS) && txflow != NC) { + + /* If CTS is disabled, we don't need to configure CTS. But to be consistent with + * RTS code above, we still configure CTS. */ + if (txflow != NC) { // Check if CTS pin matches. uint32_t uart_cts = pinmap_peripheral(txflow, PinMap_UART_CTS); MBED_ASSERT(uart_cts == obj->serial.uart); @@ -302,8 +310,14 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi pinmap_pinout(txflow, PinMap_UART_CTS); // nCTS pin input is low level active uart_base->MCSR |= UART_MCSR_LEV_CTS_Msk; - // Enable CTS - uart_base->CTL |= UART_CTL_AUTO_CTS_EN_Msk; + + if (type == FlowControlCTS || type == FlowControlRTSCTS) { + // Enable CTS + uart_base->CTL |= UART_CTL_AUTO_CTS_EN_Msk; + } else { + // Disable CTS + uart_base->CTL &= ~UART_CTL_AUTO_CTS_EN_Msk; + } } } diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/serial_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/serial_api.c index 002f23ef48..ef11b5efc9 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/serial_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/serial_api.c @@ -343,11 +343,8 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) { UART_T *uart_base = (UART_T *) NU_MODBASE(obj->serial.uart); - - // First, disable flow control completely. - uart_base->INTEN &= ~(UART_INTEN_ATORTSEN_Msk | UART_INTEN_ATOCTSEN_Msk); - if ((type == FlowControlRTS || type == FlowControlRTSCTS) && rxflow != NC) { + if (rxflow != NC) { // Check if RTS pin matches. uint32_t uart_rts = pinmap_peripheral(rxflow, PinMap_UART_RTS); MBED_ASSERT(uart_rts == obj->serial.uart); @@ -355,14 +352,24 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi pinmap_pinout(rxflow, PinMap_UART_RTS); // nRTS pin output is low level active uart_base->MODEM |= UART_MODEM_RTSACTLV_Msk; - uart_base->MODEM &= ~UART_MODEM_RTS_Msk; - + // Configure RTS trigger level to 8 bytes uart_base->FIFO = (uart_base->FIFO & ~UART_FIFO_RTSTRGLV_Msk) | UART_FIFO_RTSTRGLV_8BYTES; - // Enable RTS - uart_base->INTEN |= UART_INTEN_ATORTSEN_Msk; + + if (type == FlowControlRTS || type == FlowControlRTSCTS) { + // Enable RTS + uart_base->INTEN |= UART_INTEN_ATORTSEN_Msk; + } else { + // Disable RTS + uart_base->INTEN &= ~UART_INTEN_ATORTSEN_Msk; + /* Drive nRTS pin output to low-active. Allow the peer to be able to send data + * even though its CTS is still enabled. */ + uart_base->MODEM &= ~UART_MODEM_RTS_Msk; + } } - - if ((type == FlowControlCTS || type == FlowControlRTSCTS) && txflow != NC) { + + /* If CTS is disabled, we don't need to configure CTS. But to be consistent with + * RTS code above, we still configure CTS. */ + if (txflow != NC) { // Check if CTS pin matches. uint32_t uart_cts = pinmap_peripheral(txflow, PinMap_UART_CTS); MBED_ASSERT(uart_cts == obj->serial.uart); @@ -370,8 +377,14 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi pinmap_pinout(txflow, PinMap_UART_CTS); // nCTS pin input is low level active uart_base->MODEMSTS |= UART_MODEMSTS_CTSACTLV_Msk; - // Enable CTS - uart_base->INTEN |= UART_INTEN_ATOCTSEN_Msk; + + if (type == FlowControlCTS || type == FlowControlRTSCTS) { + // Enable CTS + uart_base->INTEN |= UART_INTEN_ATOCTSEN_Msk; + } else { + // Disable CTS + uart_base->INTEN &= ~UART_INTEN_ATOCTSEN_Msk; + } } }