7
7
#include "py/mpstate.h"
8
8
9
9
#include "mpconfigboard.h"
10
+ #include "mphalport.h"
11
+
12
+ // Store received characters on our own so that we can filter control characters
13
+ // and act immediately on CTRL-C for example.
14
+ // This is adapted from asf/thirdparty/wireless/addons/sio2host
15
+
16
+ // Receive buffer
17
+ static uint8_t usb_rx_buf [USB_RX_BUF_SIZE ];
18
+
19
+ // Receive buffer head
20
+ static uint8_t usb_rx_buf_head ;
21
+
22
+ // Receive buffer tail
23
+ static uint8_t usb_rx_buf_tail ;
24
+
25
+ // Number of bytes in receive buffer
26
+ static volatile uint8_t usb_rx_count ;
10
27
11
28
static volatile bool mp_cdc_enabled = false;
29
+
30
+ void mp_keyboard_interrupt (void );
31
+ int interrupt_char ;
32
+
12
33
extern struct usart_module usart_instance ;
13
34
14
35
bool mp_cdc_enable (uint8_t port )
@@ -22,11 +43,71 @@ void mp_cdc_disable(uint8_t port)
22
43
mp_cdc_enabled = false;
23
44
}
24
45
46
+ void usb_rx_notify (void )
47
+ {
48
+ if (mp_cdc_enabled ) {
49
+ while (udi_cdc_is_rx_ready ()) {
50
+ uint8_t c ;
51
+ c = udi_cdc_getc ();
52
+
53
+ if (c == interrupt_char ) {
54
+ mp_keyboard_interrupt ();
55
+ // Don't put the interrupt into the buffer, just continue.
56
+ continue ;
57
+ }
58
+
59
+ // Introducing critical section to avoid buffer corruption.
60
+ cpu_irq_disable ();
61
+
62
+ // The count of characters present in receive buffer is
63
+ // incremented.
64
+ usb_rx_count ++ ;
65
+ usb_rx_buf [usb_rx_buf_tail ] = c ;
66
+
67
+ if ((USB_RX_BUF_SIZE - 1 ) == usb_rx_buf_tail ) {
68
+ // Reached the end of buffer, revert back to beginning of
69
+ // buffer.
70
+ usb_rx_buf_tail = 0x00 ;
71
+ } else {
72
+ usb_rx_buf_tail ++ ;
73
+ }
74
+
75
+ cpu_irq_enable ();
76
+ }
77
+ }
78
+ }
79
+
80
+ int receive_usb () {
81
+ if (0 == usb_rx_count ) {
82
+ return 0 ;
83
+ }
84
+
85
+ if (USB_RX_BUF_SIZE <= usb_rx_count ) {
86
+ // Bytes between head and tail are overwritten by new data. The
87
+ // oldest data in buffer is the one to which the tail is pointing. So
88
+ // reading operation should start from the tail.
89
+ usb_rx_buf_head = usb_rx_buf_tail ;
90
+
91
+ // This is a buffer overflow case.But still only the number of bytes
92
+ // equivalent to full buffer size are useful.
93
+ usb_rx_count = USB_RX_BUF_SIZE ;
94
+ }
95
+
96
+ // Copy from head.
97
+ int data = usb_rx_buf [usb_rx_buf_head ];
98
+ usb_rx_buf_head ++ ;
99
+ usb_rx_count -- ;
100
+ if ((USB_RX_BUF_SIZE ) == usb_rx_buf_head ) {
101
+ usb_rx_buf_head = 0 ;
102
+ }
103
+ return data ;
104
+ }
105
+
25
106
int mp_hal_stdin_rx_chr (void ) {
26
107
for (;;) {
27
108
#ifdef USB_REPL
28
- if (mp_cdc_enabled && udi_cdc_is_rx_ready () ) {
29
- return udi_cdc_getc ();
109
+ if (mp_cdc_enabled && usb_rx_count > 0 ) {
110
+ return receive_usb ();
30
111
}
31
112
#endif
32
113
#ifdef UART_REPL
@@ -41,10 +122,6 @@ int mp_hal_stdin_rx_chr(void) {
41
122
}
42
123
}
43
124
44
- //void mp_hal_stdout_tx_str(const char *str) {
45
- // mp_hal_stdout_tx_strn(str, strlen(str));
46
- //}
47
-
48
125
void mp_hal_stdout_tx_strn (const char * str , size_t len ) {
49
126
#ifdef UART_REPL
50
127
usart_write_buffer_wait (& usart_instance , (uint8_t * ) str , len );
@@ -57,6 +134,14 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) {
57
134
#endif
58
135
}
59
136
137
+ void mp_hal_set_interrupt_char (int c ) {
138
+ if (c != -1 ) {
139
+ mp_obj_exception_clear_traceback (MP_STATE_PORT (mp_kbd_exception ));
140
+ }
141
+ extern int interrupt_char ;
142
+ interrupt_char = c ;
143
+ }
144
+
60
145
void mp_hal_delay_ms (mp_uint_t delay ) {
61
146
delay_ms (delay );
62
147
}
0 commit comments