77#include <shell/shell_uart.h>
88#include <uart.h>
99#include <init.h>
10+ #include <logging/log.h>
1011
11- SHELL_UART_DEFINE (shell_transport_uart );
12+ #define LOG_MODULE_NAME shell_uart
13+ LOG_MODULE_REGISTER (shell_uart );
14+
15+ #ifdef CONFIG_SHELL_BACKEND_SERIAL_RX_POLL_PERIOD
16+ #define RX_POLL_PERIOD CONFIG_SHELL_BACKEND_SERIAL_RX_POLL_PERIOD
17+ #else
18+ #define RX_POLL_PERIOD 0
19+ #endif
20+
21+ SHELL_UART_DEFINE (shell_transport_uart ,
22+ CONFIG_SHELL_BACKEND_SERIAL_TX_RING_BUFFER_SIZE ,
23+ CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE );
1224SHELL_DEFINE (uart_shell , "uart:~$ " , & shell_transport_uart , 10 ,
1325 SHELL_FLAG_OLF_CRLF );
1426
15- static void timer_handler (struct k_timer * timer )
27+ #ifdef CONFIG_UART_INTERRUPT_DRIVEN
28+ static void uart_rx_handle (const struct shell_uart * sh_uart )
1629{
17- struct shell_uart * sh_uart =
18- CONTAINER_OF (timer , struct shell_uart , timer );
30+ u8_t * data ;
31+ u32_t len ;
32+ u32_t rd_len ;
33+ bool new_data = false;
34+
35+ do {
36+ len = ring_buf_put_claim (sh_uart -> rx_ringbuf , & data ,
37+ sh_uart -> rx_ringbuf -> size );
38+ rd_len = uart_fifo_read (sh_uart -> ctrl_blk -> dev , data , len );
39+
40+ if (rd_len ) {
41+ new_data = true;
42+ }
43+
44+ ring_buf_put_finish (sh_uart -> rx_ringbuf , rd_len );
45+ } while (rd_len && (rd_len == len ));
46+
47+ if (new_data ) {
48+ sh_uart -> ctrl_blk -> handler (SHELL_TRANSPORT_EVT_RX_RDY ,
49+ sh_uart -> ctrl_blk -> context );
50+ }
51+ }
1952
20- if (uart_poll_in (sh_uart -> dev , sh_uart -> rx ) == 0 ) {
21- sh_uart -> rx_cnt = 1 ;
22- sh_uart -> handler (SHELL_TRANSPORT_EVT_RX_RDY , sh_uart -> context );
53+ static void uart_tx_handle (const struct shell_uart * sh_uart )
54+ {
55+ u32_t len ;
56+ u8_t * data ;
57+ int err ;
58+ struct device * dev = sh_uart -> ctrl_blk -> dev ;
59+
60+ len = ring_buf_get_claim (sh_uart -> tx_ringbuf , & data ,
61+ sh_uart -> tx_ringbuf -> size );
62+ if (len ) {
63+ len = uart_fifo_fill (dev , data , len );
64+ err = ring_buf_get_finish (sh_uart -> tx_ringbuf , len );
65+ __ASSERT_NO_MSG (err == 0 );
66+ } else {
67+ uart_irq_tx_disable (dev );
68+ sh_uart -> ctrl_blk -> tx_busy = 0 ;
2369 }
70+
71+ sh_uart -> ctrl_blk -> handler (SHELL_TRANSPORT_EVT_TX_RDY ,
72+ sh_uart -> ctrl_blk -> context );
2473}
2574
75+ static void uart_callback (void * user_data )
76+ {
77+ const struct shell_uart * sh_uart = (struct shell_uart * )user_data ;
78+ struct device * dev = sh_uart -> ctrl_blk -> dev ;
79+
80+ uart_irq_update (dev );
81+
82+ if (uart_irq_rx_ready (dev )) {
83+ uart_rx_handle (sh_uart );
84+ }
85+
86+ if (uart_irq_tx_ready (dev )) {
87+ uart_tx_handle (sh_uart );
88+ }
89+ }
90+ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
91+
92+ static void uart_irq_init (const struct shell_uart * sh_uart )
93+ {
94+ #ifdef CONFIG_UART_INTERRUPT_DRIVEN
95+ struct device * dev = sh_uart -> ctrl_blk -> dev ;
96+
97+ uart_irq_callback_user_data_set (dev , uart_callback , (void * )sh_uart );
98+ uart_irq_rx_enable (dev );
99+ #endif
100+ }
101+
102+ static void timer_handler (struct k_timer * timer )
103+ {
104+ u8_t c ;
105+ const struct shell_uart * sh_uart = k_timer_user_data_get (timer );
106+
107+ while (uart_poll_in (sh_uart -> ctrl_blk -> dev , & c ) == 0 ) {
108+ if (ring_buf_put (sh_uart -> rx_ringbuf , & c , 1 ) == 0 ) {
109+ /* ring buffer full. */
110+ LOG_WRN ("RX ring buffer full." );
111+ }
112+ sh_uart -> ctrl_blk -> handler (SHELL_TRANSPORT_EVT_RX_RDY ,
113+ sh_uart -> ctrl_blk -> context );
114+ }
115+ }
26116
27117static int init (const struct shell_transport * transport ,
28118 const void * config ,
29119 shell_transport_handler_t evt_handler ,
30120 void * context )
31121{
32- struct shell_uart * sh_uart = (struct shell_uart * )transport -> ctx ;
33-
34- sh_uart -> dev = device_get_binding (CONFIG_UART_CONSOLE_ON_DEV_NAME );
35- sh_uart -> handler = evt_handler ;
36- sh_uart -> context = context ;
122+ const struct shell_uart * sh_uart = (struct shell_uart * )transport -> ctx ;
37123
38- k_timer_init (& sh_uart -> timer , timer_handler , NULL );
124+ sh_uart -> ctrl_blk -> dev = (struct device * )config ;
125+ sh_uart -> ctrl_blk -> handler = evt_handler ;
126+ sh_uart -> ctrl_blk -> context = context ;
39127
40- k_timer_start (& sh_uart -> timer , 20 , 20 );
128+ if (IS_ENABLED (CONFIG_UART_INTERRUPT_DRIVEN )) {
129+ uart_irq_init (sh_uart );
130+ } else {
131+ k_timer_init (sh_uart -> timer , timer_handler , NULL );
132+ k_timer_user_data_set (sh_uart -> timer , (void * )sh_uart );
133+ k_timer_start (sh_uart -> timer , RX_POLL_PERIOD , RX_POLL_PERIOD );
134+ }
41135
42136 return 0 ;
43137}
@@ -49,22 +143,54 @@ static int uninit(const struct shell_transport *transport)
49143
50144static int enable (const struct shell_transport * transport , bool blocking )
51145{
146+ const struct shell_uart * sh_uart = (struct shell_uart * )transport -> ctx ;
147+
148+ sh_uart -> ctrl_blk -> blocking = blocking ;
149+
150+ if (blocking ) {
151+ if (!IS_ENABLED (CONFIG_UART_INTERRUPT_DRIVEN )) {
152+ k_timer_stop (sh_uart -> timer );
153+ }
154+ #ifdef CONFIG_UART_INTERRUPT_DRIVEN
155+ uart_irq_rx_disable (sh_uart -> ctrl_blk -> dev );
156+ uart_irq_tx_disable (sh_uart -> ctrl_blk -> dev );
157+ #endif
158+ }
159+
52160 return 0 ;
53161}
54162
163+ static void irq_write (const struct shell_uart * sh_uart , const void * data ,
164+ size_t length , size_t * cnt )
165+ {
166+ * cnt = ring_buf_put (sh_uart -> tx_ringbuf , data , length );
167+
168+ if (atomic_set (& sh_uart -> ctrl_blk -> tx_busy , 1 ) == 0 ) {
169+ #ifdef CONFIG_UART_INTERRUPT_DRIVEN
170+ uart_irq_tx_enable (sh_uart -> ctrl_blk -> dev );
171+ #endif
172+ }
173+ }
174+
55175static int write (const struct shell_transport * transport ,
56176 const void * data , size_t length , size_t * cnt )
57177{
58- struct shell_uart * sh_uart = (struct shell_uart * )transport -> ctx ;
178+ const struct shell_uart * sh_uart = (struct shell_uart * )transport -> ctx ;
59179 const u8_t * data8 = (const u8_t * )data ;
60180
61- for (size_t i = 0 ; i < length ; i ++ ) {
62- uart_poll_out (sh_uart -> dev , data8 [i ]);
63- }
181+ if (IS_ENABLED (CONFIG_UART_INTERRUPT_DRIVEN ) &&
182+ !sh_uart -> ctrl_blk -> blocking ) {
183+ irq_write (sh_uart , data , length , cnt );
184+ } else {
185+ for (size_t i = 0 ; i < length ; i ++ ) {
186+ uart_poll_out (sh_uart -> ctrl_blk -> dev , data8 [i ]);
187+ }
64188
65- * cnt = length ;
189+ * cnt = length ;
66190
67- sh_uart -> handler (SHELL_TRANSPORT_EVT_TX_RDY , sh_uart -> context );
191+ sh_uart -> ctrl_blk -> handler (SHELL_TRANSPORT_EVT_TX_RDY ,
192+ sh_uart -> ctrl_blk -> context );
193+ }
68194
69195 return 0 ;
70196}
@@ -73,17 +199,8 @@ static int read(const struct shell_transport *transport,
73199 void * data , size_t length , size_t * cnt )
74200{
75201 struct shell_uart * sh_uart = (struct shell_uart * )transport -> ctx ;
76- u32_t key ;
77202
78- key = irq_lock ();
79- if (sh_uart -> rx_cnt ) {
80- memcpy (data , sh_uart -> rx , 1 );
81- sh_uart -> rx_cnt = 0 ;
82- * cnt = 1 ;
83- } else {
84- * cnt = 0 ;
85- }
86- irq_unlock (key );
203+ * cnt = ring_buf_get (sh_uart -> rx_ringbuf , data , length );
87204
88205 return 0 ;
89206}
@@ -99,7 +216,9 @@ const struct shell_transport_api shell_uart_transport_api = {
99216static int enable_shell_uart (struct device * arg )
100217{
101218 ARG_UNUSED (arg );
102- shell_init (& uart_shell , NULL , true, true, LOG_LEVEL_INF );
219+ struct device * dev =
220+ device_get_binding (CONFIG_UART_CONSOLE_ON_DEV_NAME );
221+ shell_init (& uart_shell , dev , true, true, LOG_LEVEL_INF );
103222 return 0 ;
104223}
105224SYS_INIT (enable_shell_uart , POST_KERNEL , 0 );
0 commit comments