36
36
#include "driver/rtc_io.h"
37
37
#include "hal/rtc_io_ll.h"
38
38
#include "driver/lp_io.h"
39
+ #if SOC_LP_GPIO_MATRIX_SUPPORTED
40
+ #include "soc/lp_gpio_pins.h"
41
+ #endif
39
42
#endif
40
43
#include "clk_ctrl_os.h"
41
44
#include "esp_pm.h"
@@ -109,6 +112,11 @@ static const char *UART_TAG = "uart";
109
112
.hal.dev = UART_LL_GET_HW(uart_num), \
110
113
INIT_CRIT_SECTION_LOCK_IN_STRUCT(spinlock) \
111
114
.hw_enabled = false, \
115
+ .tx_io_num = -1, \
116
+ .rx_io_num = -1, \
117
+ .rts_io_num = -1, \
118
+ .cts_io_num = -1, \
119
+ .io_reserved_mask = 0, \
112
120
}
113
121
114
122
typedef struct {
@@ -170,6 +178,11 @@ typedef struct {
170
178
uart_hal_context_t hal ; /*!< UART hal context*/
171
179
DECLARE_CRIT_SECTION_LOCK_IN_STRUCT (spinlock )
172
180
bool hw_enabled ;
181
+ int tx_io_num ;
182
+ int rx_io_num ;
183
+ int rts_io_num ;
184
+ int cts_io_num ;
185
+ uint64_t io_reserved_mask ;
173
186
} uart_context_t ;
174
187
175
188
static uart_obj_t * p_uart_obj [UART_NUM_MAX ] = {0 };
@@ -707,8 +720,66 @@ static bool uart_try_set_iomux_pin(uart_port_t uart_num, int io_num, uint32_t id
707
720
return true;
708
721
}
709
722
710
- //internal signal can be output to multiple GPIO pads
711
- //only one GPIO pad can connect with input signal
723
+ static void uart_release_pin (uart_port_t uart_num )
724
+ {
725
+ if (uart_num >= UART_NUM_MAX ) {
726
+ return ;
727
+ }
728
+ if (uart_context [uart_num ].tx_io_num >= 0 ) {
729
+ gpio_output_disable (uart_context [uart_num ].tx_io_num );
730
+ #if (SOC_UART_LP_NUM >= 1 )
731
+ if (!(uart_num < SOC_UART_HP_NUM )) {
732
+ rtc_gpio_deinit (uart_context [uart_num ].tx_io_num );
733
+ }
734
+ #endif
735
+ }
736
+
737
+ if (uart_context [uart_num ].rx_io_num >= 0 ) {
738
+ if (uart_num < SOC_UART_HP_NUM ) {
739
+ esp_rom_gpio_connect_in_signal (GPIO_MATRIX_CONST_ONE_INPUT , UART_PERIPH_SIGNAL (uart_num , SOC_UART_RX_PIN_IDX ), false);
740
+ }
741
+ #if (SOC_UART_LP_NUM >= 1 )
742
+ else {
743
+ #if SOC_LP_GPIO_MATRIX_SUPPORTED
744
+ lp_gpio_connect_in_signal (LP_GPIO_MATRIX_CONST_ONE_INPUT , UART_PERIPH_SIGNAL (uart_num , SOC_UART_RX_PIN_IDX ), false);
745
+ #endif
746
+ rtc_gpio_deinit (uart_context [uart_num ].rx_io_num );
747
+ }
748
+ #endif
749
+ }
750
+
751
+ if (uart_context [uart_num ].rts_io_num >= 0 ) {
752
+ gpio_output_disable (uart_context [uart_num ].rts_io_num );
753
+ #if (SOC_UART_LP_NUM >= 1 )
754
+ if (!(uart_num < SOC_UART_HP_NUM )) {
755
+ rtc_gpio_deinit (uart_context [uart_num ].rts_io_num );
756
+ }
757
+ #endif
758
+ }
759
+
760
+ if (uart_context [uart_num ].cts_io_num >= 0 ) {
761
+ if (uart_num < SOC_UART_HP_NUM ) {
762
+ esp_rom_gpio_connect_in_signal (GPIO_MATRIX_CONST_ZERO_INPUT , UART_PERIPH_SIGNAL (uart_num , SOC_UART_CTS_PIN_IDX ), false);
763
+ }
764
+ #if (SOC_UART_LP_NUM >= 1 )
765
+ else {
766
+ #if SOC_LP_GPIO_MATRIX_SUPPORTED
767
+ lp_gpio_connect_in_signal (LP_GPIO_MATRIX_CONST_ZERO_INPUT , UART_PERIPH_SIGNAL (uart_num , SOC_UART_CTS_PIN_IDX ), false);
768
+ #endif
769
+ rtc_gpio_deinit (uart_context [uart_num ].cts_io_num );
770
+ }
771
+ #endif
772
+ }
773
+
774
+ esp_gpio_revoke (uart_context [uart_num ].io_reserved_mask );
775
+
776
+ uart_context [uart_num ].tx_io_num = -1 ;
777
+ uart_context [uart_num ].rx_io_num = -1 ;
778
+ uart_context [uart_num ].rts_io_num = -1 ;
779
+ uart_context [uart_num ].cts_io_num = -1 ;
780
+ uart_context [uart_num ].io_reserved_mask = 0 ;
781
+ }
782
+
712
783
esp_err_t uart_set_pin (uart_port_t uart_num , int tx_io_num , int rx_io_num , int rts_io_num , int cts_io_num )
713
784
{
714
785
ESP_RETURN_ON_FALSE ((uart_num >= 0 ), ESP_FAIL , UART_TAG , "uart_num error" );
@@ -740,6 +811,9 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
740
811
}
741
812
#endif
742
813
814
+ // First, release previously configured IOs if there is
815
+ uart_release_pin (uart_num );
816
+
743
817
// Potential IO reserved mask
744
818
uint64_t io_reserve_mask = 0 ;
745
819
io_reserve_mask |= (tx_io_num > 0 ? BIT64 (tx_io_num ) : 0 );
@@ -752,42 +826,48 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
752
826
bool tx_rx_same_io = (tx_io_num == rx_io_num );
753
827
754
828
/* In the following statements, if the io_num is negative, no need to configure anything. */
755
- if (tx_io_num >= 0 && (tx_rx_same_io || !uart_try_set_iomux_pin (uart_num , tx_io_num , SOC_UART_TX_PIN_IDX ))) {
756
- if (uart_num < SOC_UART_HP_NUM ) {
757
- gpio_func_sel (tx_io_num , PIN_FUNC_GPIO );
758
- esp_rom_gpio_connect_out_signal (tx_io_num , UART_PERIPH_SIGNAL (uart_num , SOC_UART_TX_PIN_IDX ), 0 , 0 );
759
- // output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected
760
- // (output enabled too early may cause unnecessary level change at the pad)
761
- }
829
+ if (tx_io_num >= 0 ) {
830
+ uart_context [uart_num ].tx_io_num = tx_io_num ;
831
+ if (tx_rx_same_io || !uart_try_set_iomux_pin (uart_num , tx_io_num , SOC_UART_TX_PIN_IDX )) {
832
+ if (uart_num < SOC_UART_HP_NUM ) {
833
+ gpio_func_sel (tx_io_num , PIN_FUNC_GPIO );
834
+ esp_rom_gpio_connect_out_signal (tx_io_num , UART_PERIPH_SIGNAL (uart_num , SOC_UART_TX_PIN_IDX ), 0 , 0 );
835
+ // output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected
836
+ // (output enabled too early may cause unnecessary level change at the pad)
837
+ }
762
838
#if SOC_LP_GPIO_MATRIX_SUPPORTED
763
- else {
764
- rtc_gpio_init (tx_io_num ); // set as a LP_GPIO pin
765
- lp_gpio_connect_out_signal (tx_io_num , UART_PERIPH_SIGNAL (uart_num , SOC_UART_TX_PIN_IDX ), 0 , 0 );
766
- // output enable is set inside lp_gpio_connect_out_signal func after the signal is connected
767
- }
839
+ else {
840
+ rtc_gpio_init (tx_io_num ); // set as a LP_GPIO pin
841
+ lp_gpio_connect_out_signal (tx_io_num , UART_PERIPH_SIGNAL (uart_num , SOC_UART_TX_PIN_IDX ), 0 , 0 );
842
+ // output enable is set inside lp_gpio_connect_out_signal func after the signal is connected
843
+ }
768
844
#endif
845
+ }
769
846
}
770
847
771
- if (rx_io_num >= 0 && (tx_rx_same_io || !uart_try_set_iomux_pin (uart_num , rx_io_num , SOC_UART_RX_PIN_IDX ))) {
772
- io_reserve_mask &= ~BIT64 (rx_io_num ); // input IO via GPIO matrix does not need to be reserved
773
- if (uart_num < SOC_UART_HP_NUM ) {
774
- gpio_input_enable (rx_io_num );
775
- esp_rom_gpio_connect_in_signal (rx_io_num , UART_PERIPH_SIGNAL (uart_num , SOC_UART_RX_PIN_IDX ), 0 );
776
- }
777
- #if SOC_LP_GPIO_MATRIX_SUPPORTED
778
- else {
779
- rtc_gpio_mode_t mode = (tx_rx_same_io ? RTC_GPIO_MODE_INPUT_OUTPUT : RTC_GPIO_MODE_INPUT_ONLY );
780
- rtc_gpio_set_direction (rx_io_num , mode );
781
- if (!tx_rx_same_io ) { // set the same pin again as a LP_GPIO will overwrite connected out_signal, not desired, so skip
782
- rtc_gpio_init (rx_io_num ); // set as a LP_GPIO pin
848
+ if (rx_io_num >= 0 ) {
849
+ uart_context [uart_num ].rx_io_num = rx_io_num ;
850
+ if (tx_rx_same_io || !uart_try_set_iomux_pin (uart_num , rx_io_num , SOC_UART_RX_PIN_IDX )) {
851
+ io_reserve_mask &= ~BIT64 (rx_io_num ); // input IO via GPIO matrix does not need to be reserved
852
+ if (uart_num < SOC_UART_HP_NUM ) {
853
+ gpio_input_enable (rx_io_num );
854
+ esp_rom_gpio_connect_in_signal (rx_io_num , UART_PERIPH_SIGNAL (uart_num , SOC_UART_RX_PIN_IDX ), 0 );
783
855
}
856
+ #if SOC_LP_GPIO_MATRIX_SUPPORTED
857
+ else {
858
+ rtc_gpio_mode_t mode = (tx_rx_same_io ? RTC_GPIO_MODE_INPUT_OUTPUT : RTC_GPIO_MODE_INPUT_ONLY );
859
+ rtc_gpio_set_direction (rx_io_num , mode );
860
+ if (!tx_rx_same_io ) { // set the same pin again as a LP_GPIO will overwrite connected out_signal, not desired, so skip
861
+ rtc_gpio_init (rx_io_num ); // set as a LP_GPIO pin
862
+ }
784
863
785
- lp_gpio_connect_in_signal (rx_io_num , UART_PERIPH_SIGNAL (uart_num , SOC_UART_RX_PIN_IDX ), 0 );
786
- }
864
+ lp_gpio_connect_in_signal (rx_io_num , UART_PERIPH_SIGNAL (uart_num , SOC_UART_RX_PIN_IDX ), 0 );
865
+ }
787
866
#endif
867
+ }
788
868
}
789
869
790
- if (rts_io_num >= 0 && !uart_try_set_iomux_pin (uart_num , rts_io_num , SOC_UART_RTS_PIN_IDX )) {
870
+ if (rts_io_num >= 0 && ( uart_context [ uart_num ]. rts_io_num = rts_io_num , !uart_try_set_iomux_pin (uart_num , rts_io_num , SOC_UART_RTS_PIN_IDX ) )) {
791
871
if (uart_num < SOC_UART_HP_NUM ) {
792
872
gpio_func_sel (rts_io_num , PIN_FUNC_GPIO );
793
873
esp_rom_gpio_connect_out_signal (rts_io_num , UART_PERIPH_SIGNAL (uart_num , SOC_UART_RTS_PIN_IDX ), 0 , 0 );
@@ -802,7 +882,7 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
802
882
#endif
803
883
}
804
884
805
- if (cts_io_num >= 0 && !uart_try_set_iomux_pin (uart_num , cts_io_num , SOC_UART_CTS_PIN_IDX )) {
885
+ if (cts_io_num >= 0 && ( uart_context [ uart_num ]. cts_io_num = cts_io_num , !uart_try_set_iomux_pin (uart_num , cts_io_num , SOC_UART_CTS_PIN_IDX ) )) {
806
886
io_reserve_mask &= ~BIT64 (cts_io_num ); // input IO via GPIO matrix does not need to be reserved
807
887
if (uart_num < SOC_UART_HP_NUM ) {
808
888
gpio_pullup_en (cts_io_num );
@@ -819,6 +899,7 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
819
899
}
820
900
821
901
// IO reserve
902
+ uart_context [uart_num ].io_reserved_mask = io_reserve_mask ;
822
903
uint64_t old_busy_mask = esp_gpio_reserve (io_reserve_mask );
823
904
uint64_t conflict_mask = old_busy_mask & io_reserve_mask ;
824
905
while (conflict_mask > 0 ) {
@@ -1801,6 +1882,9 @@ esp_err_t uart_driver_delete(uart_port_t uart_num)
1801
1882
ESP_LOGI (UART_TAG , "ALREADY NULL" );
1802
1883
return ESP_OK ;
1803
1884
}
1885
+
1886
+ uart_release_pin (uart_num );
1887
+
1804
1888
esp_intr_free (p_uart_obj [uart_num ]-> intr_handle );
1805
1889
uart_disable_rx_intr (uart_num );
1806
1890
uart_disable_tx_intr (uart_num );
0 commit comments