|
|
|
|
@@ -5,14 +5,44 @@
|
|
|
|
|
#include "usb_lld.h"
|
|
|
|
|
#include "tty.h"
|
|
|
|
|
|
|
|
|
|
#define BUFSIZE 128
|
|
|
|
|
static chopstx_intr_t usb_intr;
|
|
|
|
|
|
|
|
|
|
struct line_coding
|
|
|
|
|
{
|
|
|
|
|
uint32_t bitrate;
|
|
|
|
|
uint8_t format;
|
|
|
|
|
uint8_t paritytype;
|
|
|
|
|
uint8_t datatype;
|
|
|
|
|
} __attribute__((packed));
|
|
|
|
|
|
|
|
|
|
static const struct line_coding line_coding0 = {
|
|
|
|
|
115200, /* baud rate: 115200 */
|
|
|
|
|
0x00, /* stop bits: 1 */
|
|
|
|
|
0x00, /* parity: none */
|
|
|
|
|
0x08 /* bits: 8 */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Currently, we only support a single TTY.
|
|
|
|
|
*
|
|
|
|
|
* It is possible to extend to support multiple TTYs, for multiple
|
|
|
|
|
* interfaces.
|
|
|
|
|
*
|
|
|
|
|
* In that case, add argument to TTY_OPEN function and
|
|
|
|
|
* modify TTY_GET function to get the TTY structure. Functions which
|
|
|
|
|
* directy accesses TTY0 (usb_cb_device_reset and usb_cb_handle_event)
|
|
|
|
|
* should be modified, too.
|
|
|
|
|
*
|
|
|
|
|
* Modification of TTY_MAIN thread will be also needed to echo back
|
|
|
|
|
* input for each TTY, and the thread should run if one of TTY is
|
|
|
|
|
* opened.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
struct tty {
|
|
|
|
|
chopstx_mutex_t mtx;
|
|
|
|
|
chopstx_cond_t cnd;
|
|
|
|
|
chopstx_intr_t intr;
|
|
|
|
|
uint8_t inputline[BUFSIZE]; /* Line editing is supported */
|
|
|
|
|
uint8_t send_buf[BUFSIZE]; /* Sending ring buffer for echo back */
|
|
|
|
|
uint8_t inputline[LINEBUFSIZE]; /* Line editing is supported */
|
|
|
|
|
uint8_t send_buf[LINEBUFSIZE]; /* Sending ring buffer for echo back */
|
|
|
|
|
uint32_t inputline_len : 8;
|
|
|
|
|
uint32_t send_head : 8;
|
|
|
|
|
uint32_t send_tail : 8;
|
|
|
|
|
@@ -21,9 +51,34 @@ struct tty {
|
|
|
|
|
uint32_t flag_input_avail : 1;
|
|
|
|
|
uint32_t : 2;
|
|
|
|
|
uint32_t device_state : 3; /* USB device status */
|
|
|
|
|
struct line_coding line_coding;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static struct tty tty;
|
|
|
|
|
static struct tty tty0;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Locate TTY structure from interface number or endpoint number.
|
|
|
|
|
* Currently, it always returns tty0, because we only have the one.
|
|
|
|
|
*/
|
|
|
|
|
static struct tty *
|
|
|
|
|
tty_get (int interface, uint8_t ep_num)
|
|
|
|
|
{
|
|
|
|
|
struct tty *t = &tty0;
|
|
|
|
|
|
|
|
|
|
if (interface >= 0)
|
|
|
|
|
{
|
|
|
|
|
if (interface == 0)
|
|
|
|
|
t = &tty0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (ep_num == ENDP1 || ep_num == ENDP2 || ep_num == ENDP3)
|
|
|
|
|
t = &tty0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return t;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define ENDP0_RXADDR (0x40)
|
|
|
|
|
#define ENDP0_TXADDR (0x80)
|
|
|
|
|
@@ -187,14 +242,15 @@ usb_cb_device_reset (void)
|
|
|
|
|
/* Initialize Endpoint 0 */
|
|
|
|
|
usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR, 64);
|
|
|
|
|
|
|
|
|
|
chopstx_mutex_lock (&tty.mtx);
|
|
|
|
|
tty.inputline_len = 0;
|
|
|
|
|
tty.send_head = tty.send_tail = 0;
|
|
|
|
|
tty.flag_connected = 0;
|
|
|
|
|
tty.flag_send_ready = 1;
|
|
|
|
|
tty.flag_input_avail = 0;
|
|
|
|
|
tty.device_state = ATTACHED;
|
|
|
|
|
chopstx_mutex_unlock (&tty.mtx);
|
|
|
|
|
chopstx_mutex_lock (&tty0.mtx);
|
|
|
|
|
tty0.inputline_len = 0;
|
|
|
|
|
tty0.send_head = tty0.send_tail = 0;
|
|
|
|
|
tty0.flag_connected = 0;
|
|
|
|
|
tty0.flag_send_ready = 1;
|
|
|
|
|
tty0.flag_input_avail = 0;
|
|
|
|
|
tty0.device_state = ATTACHED;
|
|
|
|
|
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
|
|
|
|
|
chopstx_mutex_unlock (&tty0.mtx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -205,31 +261,19 @@ usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, struct req_args *arg)
|
|
|
|
|
{
|
|
|
|
|
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
|
|
|
|
|
|
|
|
|
if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT)
|
|
|
|
|
if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT) && arg->index == 0
|
|
|
|
|
&& USB_SETUP_SET (req) && req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
|
|
|
|
|
{
|
|
|
|
|
struct tty *t = tty_get (arg->index, 0);
|
|
|
|
|
|
|
|
|
|
/* Open/close the connection. */
|
|
|
|
|
chopstx_mutex_lock (&tty.mtx);
|
|
|
|
|
tty.flag_connected = ((arg->value & CDC_CTRL_DTR) != 0);
|
|
|
|
|
chopstx_cond_signal (&tty.cnd);
|
|
|
|
|
chopstx_mutex_unlock (&tty.mtx);
|
|
|
|
|
chopstx_mutex_lock (&t->mtx);
|
|
|
|
|
t->flag_connected = ((arg->value & CDC_CTRL_DTR) != 0);
|
|
|
|
|
chopstx_cond_signal (&t->cnd);
|
|
|
|
|
chopstx_mutex_unlock (&t->mtx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct line_coding
|
|
|
|
|
{
|
|
|
|
|
uint32_t bitrate;
|
|
|
|
|
uint8_t format;
|
|
|
|
|
uint8_t paritytype;
|
|
|
|
|
uint8_t datatype;
|
|
|
|
|
} __attribute__((packed));
|
|
|
|
|
|
|
|
|
|
static struct line_coding line_coding = {
|
|
|
|
|
115200, /* baud rate: 115200 */
|
|
|
|
|
0x00, /* stop bits: 1 */
|
|
|
|
|
0x00, /* parity: none */
|
|
|
|
|
0x08 /* bits: 8 */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
@@ -237,15 +281,21 @@ vcom_port_data_setup (uint8_t req, uint8_t req_no, struct req_args *arg)
|
|
|
|
|
{
|
|
|
|
|
if (USB_SETUP_GET (req))
|
|
|
|
|
{
|
|
|
|
|
struct tty *t = tty_get (arg->index, 0);
|
|
|
|
|
|
|
|
|
|
if (req_no == USB_CDC_REQ_GET_LINE_CODING)
|
|
|
|
|
return usb_lld_reply_request (&line_coding, sizeof(line_coding), arg);
|
|
|
|
|
return usb_lld_reply_request (&t->line_coding,
|
|
|
|
|
sizeof (struct line_coding), arg);
|
|
|
|
|
}
|
|
|
|
|
else /* USB_SETUP_SET (req) */
|
|
|
|
|
{
|
|
|
|
|
if (req_no == USB_CDC_REQ_SET_LINE_CODING
|
|
|
|
|
&& arg->len == sizeof (line_coding))
|
|
|
|
|
&& arg->len == sizeof (struct line_coding))
|
|
|
|
|
{
|
|
|
|
|
usb_lld_set_data_to_recv (&line_coding, sizeof (line_coding));
|
|
|
|
|
struct tty *t = tty_get (arg->index, 0);
|
|
|
|
|
|
|
|
|
|
usb_lld_set_data_to_recv (&t->line_coding,
|
|
|
|
|
sizeof (struct line_coding));
|
|
|
|
|
return USB_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
else if (req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
|
|
|
|
|
@@ -348,9 +398,9 @@ usb_cb_handle_event (uint8_t event_type, uint16_t value)
|
|
|
|
|
switch (event_type)
|
|
|
|
|
{
|
|
|
|
|
case USB_EVENT_ADDRESS:
|
|
|
|
|
chopstx_mutex_lock (&tty.mtx);
|
|
|
|
|
tty.device_state = ADDRESSED;
|
|
|
|
|
chopstx_mutex_unlock (&tty.mtx);
|
|
|
|
|
chopstx_mutex_lock (&tty0.mtx);
|
|
|
|
|
tty0.device_state = ADDRESSED;
|
|
|
|
|
chopstx_mutex_unlock (&tty0.mtx);
|
|
|
|
|
return USB_SUCCESS;
|
|
|
|
|
case USB_EVENT_CONFIG:
|
|
|
|
|
current_conf = usb_lld_current_configuration ();
|
|
|
|
|
@@ -362,9 +412,9 @@ usb_cb_handle_event (uint8_t event_type, uint16_t value)
|
|
|
|
|
usb_lld_set_configuration (1);
|
|
|
|
|
for (i = 0; i < NUM_INTERFACES; i++)
|
|
|
|
|
vcom_setup_endpoints_for_interface (i, 0);
|
|
|
|
|
chopstx_mutex_lock (&tty.mtx);
|
|
|
|
|
tty.device_state = CONFIGURED;
|
|
|
|
|
chopstx_mutex_unlock (&tty.mtx);
|
|
|
|
|
chopstx_mutex_lock (&tty0.mtx);
|
|
|
|
|
tty0.device_state = CONFIGURED;
|
|
|
|
|
chopstx_mutex_unlock (&tty0.mtx);
|
|
|
|
|
}
|
|
|
|
|
else if (current_conf != value)
|
|
|
|
|
{
|
|
|
|
|
@@ -374,9 +424,9 @@ usb_cb_handle_event (uint8_t event_type, uint16_t value)
|
|
|
|
|
usb_lld_set_configuration (0);
|
|
|
|
|
for (i = 0; i < NUM_INTERFACES; i++)
|
|
|
|
|
vcom_setup_endpoints_for_interface (i, 1);
|
|
|
|
|
chopstx_mutex_lock (&tty.mtx);
|
|
|
|
|
tty.device_state = ADDRESSED;
|
|
|
|
|
chopstx_mutex_unlock (&tty.mtx);
|
|
|
|
|
chopstx_mutex_lock (&tty0.mtx);
|
|
|
|
|
tty0.device_state = ADDRESSED;
|
|
|
|
|
chopstx_mutex_unlock (&tty0.mtx);
|
|
|
|
|
}
|
|
|
|
|
/* Do nothing when current_conf == value */
|
|
|
|
|
return USB_SUCCESS;
|
|
|
|
|
@@ -423,61 +473,63 @@ usb_cb_interface (uint8_t cmd, struct req_args *arg)
|
|
|
|
|
* Put a character into the ring buffer to be send back.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
put_char_to_ringbuffer (int c)
|
|
|
|
|
put_char_to_ringbuffer (struct tty *t, int c)
|
|
|
|
|
{
|
|
|
|
|
uint32_t next = (tty.send_tail + 1) % BUFSIZE;
|
|
|
|
|
uint32_t next = (t->send_tail + 1) % LINEBUFSIZE;
|
|
|
|
|
|
|
|
|
|
if (tty.send_head == next)
|
|
|
|
|
if (t->send_head == next)
|
|
|
|
|
/* full */
|
|
|
|
|
/* All that we can do is ignore this char. */
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
tty.send_buf[tty.send_tail] = c;
|
|
|
|
|
tty.send_tail = next;
|
|
|
|
|
t->send_buf[t->send_tail] = c;
|
|
|
|
|
t->send_tail = next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Get characters from ring buffer into S.
|
|
|
|
|
*/
|
|
|
|
|
static int
|
|
|
|
|
get_chars_from_ringbuffer (uint8_t *s, int len)
|
|
|
|
|
get_chars_from_ringbuffer (struct tty *t, uint8_t *s, int len)
|
|
|
|
|
{
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
|
|
if (tty.send_head == tty.send_tail)
|
|
|
|
|
if (t->send_head == t->send_tail)
|
|
|
|
|
/* Empty */
|
|
|
|
|
return i;
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
s[i++] = tty.send_buf[tty.send_head];
|
|
|
|
|
tty.send_head = (tty.send_head + 1) % BUFSIZE;
|
|
|
|
|
s[i++] = t->send_buf[t->send_head];
|
|
|
|
|
t->send_head = (t->send_head + 1) % LINEBUFSIZE;
|
|
|
|
|
}
|
|
|
|
|
while (tty.send_head != tty.send_tail && i < len);
|
|
|
|
|
while (t->send_head != t->send_tail && i < len);
|
|
|
|
|
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
tty_echo_char (int c)
|
|
|
|
|
tty_echo_char (struct tty *t, int c)
|
|
|
|
|
{
|
|
|
|
|
put_char_to_ringbuffer (c);
|
|
|
|
|
put_char_to_ringbuffer (t, c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
usb_cb_tx_done (uint8_t ep_num)
|
|
|
|
|
{
|
|
|
|
|
struct tty *t = tty_get (-1, ep_num);
|
|
|
|
|
|
|
|
|
|
if (ep_num == ENDP1)
|
|
|
|
|
{
|
|
|
|
|
chopstx_mutex_lock (&tty.mtx);
|
|
|
|
|
if (tty.flag_send_ready == 0)
|
|
|
|
|
chopstx_mutex_lock (&t->mtx);
|
|
|
|
|
if (t->flag_send_ready == 0)
|
|
|
|
|
{
|
|
|
|
|
tty.flag_send_ready = 1;
|
|
|
|
|
chopstx_cond_signal (&tty.cnd);
|
|
|
|
|
t->flag_send_ready = 1;
|
|
|
|
|
chopstx_cond_signal (&t->cnd);
|
|
|
|
|
}
|
|
|
|
|
chopstx_mutex_unlock (&tty.mtx);
|
|
|
|
|
chopstx_mutex_unlock (&t->mtx);
|
|
|
|
|
}
|
|
|
|
|
else if (ep_num == ENDP2)
|
|
|
|
|
{
|
|
|
|
|
@@ -487,60 +539,60 @@ usb_cb_tx_done (uint8_t ep_num)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
tty_input_char (int c)
|
|
|
|
|
tty_input_char (struct tty *t, int c)
|
|
|
|
|
{
|
|
|
|
|
unsigned int i;
|
|
|
|
|
int r = 0;
|
|
|
|
|
|
|
|
|
|
/* Process DEL, C-U, C-R, and RET as editing command. */
|
|
|
|
|
chopstx_mutex_lock (&tty.mtx);
|
|
|
|
|
chopstx_mutex_lock (&t->mtx);
|
|
|
|
|
switch (c)
|
|
|
|
|
{
|
|
|
|
|
case 0x0d: /* Control-M */
|
|
|
|
|
tty_echo_char (0x0d);
|
|
|
|
|
tty_echo_char (0x0a);
|
|
|
|
|
tty.flag_input_avail = 1;
|
|
|
|
|
tty_echo_char (t, 0x0d);
|
|
|
|
|
tty_echo_char (t, 0x0a);
|
|
|
|
|
t->flag_input_avail = 1;
|
|
|
|
|
r = 1;
|
|
|
|
|
chopstx_cond_signal (&tty.cnd);
|
|
|
|
|
chopstx_cond_signal (&t->cnd);
|
|
|
|
|
break;
|
|
|
|
|
case 0x12: /* Control-R */
|
|
|
|
|
tty_echo_char ('^');
|
|
|
|
|
tty_echo_char ('R');
|
|
|
|
|
tty_echo_char (0x0d);
|
|
|
|
|
tty_echo_char (0x0a);
|
|
|
|
|
for (i = 0; i < tty.inputline_len; i++)
|
|
|
|
|
tty_echo_char (tty.inputline[i]);
|
|
|
|
|
tty_echo_char (t, '^');
|
|
|
|
|
tty_echo_char (t, 'R');
|
|
|
|
|
tty_echo_char (t, 0x0d);
|
|
|
|
|
tty_echo_char (t, 0x0a);
|
|
|
|
|
for (i = 0; i < t->inputline_len; i++)
|
|
|
|
|
tty_echo_char (t, t->inputline[i]);
|
|
|
|
|
break;
|
|
|
|
|
case 0x15: /* Control-U */
|
|
|
|
|
for (i = 0; i < tty.inputline_len; i++)
|
|
|
|
|
for (i = 0; i < t->inputline_len; i++)
|
|
|
|
|
{
|
|
|
|
|
tty_echo_char (0x08);
|
|
|
|
|
tty_echo_char (0x20);
|
|
|
|
|
tty_echo_char (0x08);
|
|
|
|
|
tty_echo_char (t, 0x08);
|
|
|
|
|
tty_echo_char (t, 0x20);
|
|
|
|
|
tty_echo_char (t, 0x08);
|
|
|
|
|
}
|
|
|
|
|
tty.inputline_len = 0;
|
|
|
|
|
t->inputline_len = 0;
|
|
|
|
|
break;
|
|
|
|
|
case 0x7f: /* DEL */
|
|
|
|
|
if (tty.inputline_len > 0)
|
|
|
|
|
if (t->inputline_len > 0)
|
|
|
|
|
{
|
|
|
|
|
tty_echo_char (0x08);
|
|
|
|
|
tty_echo_char (0x20);
|
|
|
|
|
tty_echo_char (0x08);
|
|
|
|
|
tty.inputline_len--;
|
|
|
|
|
tty_echo_char (t, 0x08);
|
|
|
|
|
tty_echo_char (t, 0x20);
|
|
|
|
|
tty_echo_char (t, 0x08);
|
|
|
|
|
t->inputline_len--;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if (tty.inputline_len < sizeof (tty.inputline))
|
|
|
|
|
if (t->inputline_len < sizeof (t->inputline))
|
|
|
|
|
{
|
|
|
|
|
tty_echo_char (c);
|
|
|
|
|
tty.inputline[tty.inputline_len++] = c;
|
|
|
|
|
tty_echo_char (t, c);
|
|
|
|
|
t->inputline[t->inputline_len++] = c;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
/* Beep */
|
|
|
|
|
tty_echo_char (0x0a);
|
|
|
|
|
tty_echo_char (t, 0x0a);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
chopstx_mutex_unlock (&tty.mtx);
|
|
|
|
|
chopstx_mutex_unlock (&t->mtx);
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -548,6 +600,7 @@ void
|
|
|
|
|
usb_cb_rx_ready (uint8_t ep_num)
|
|
|
|
|
{
|
|
|
|
|
uint8_t recv_buf[64];
|
|
|
|
|
struct tty *t = tty_get (-1, ep_num);
|
|
|
|
|
|
|
|
|
|
if (ep_num == ENDP3)
|
|
|
|
|
{
|
|
|
|
|
@@ -556,13 +609,13 @@ usb_cb_rx_ready (uint8_t ep_num)
|
|
|
|
|
r = usb_lld_rx_data_len (ENDP3);
|
|
|
|
|
usb_lld_rxcpy (recv_buf, ep_num, 0, r);
|
|
|
|
|
for (i = 0; i < r; i++)
|
|
|
|
|
if (tty_input_char (recv_buf[i]))
|
|
|
|
|
if (tty_input_char (t, recv_buf[i]))
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
chopstx_mutex_lock (&tty.mtx);
|
|
|
|
|
if (tty.flag_input_avail == 0)
|
|
|
|
|
chopstx_mutex_lock (&t->mtx);
|
|
|
|
|
if (t->flag_input_avail == 0)
|
|
|
|
|
usb_lld_rx_enable (ENDP3);
|
|
|
|
|
chopstx_mutex_unlock (&tty.mtx);
|
|
|
|
|
chopstx_mutex_unlock (&t->mtx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -578,25 +631,25 @@ const size_t __stacksize_tty = (size_t)&__process3_stack_size__;
|
|
|
|
|
struct tty *
|
|
|
|
|
tty_open (void)
|
|
|
|
|
{
|
|
|
|
|
chopstx_mutex_init (&tty.mtx);
|
|
|
|
|
chopstx_cond_init (&tty.cnd);
|
|
|
|
|
tty.inputline_len = 0;
|
|
|
|
|
tty.send_head = tty.send_tail = 0;
|
|
|
|
|
tty.flag_connected = 0;
|
|
|
|
|
tty.flag_send_ready = 1;
|
|
|
|
|
tty.flag_input_avail = 0;
|
|
|
|
|
tty.device_state = UNCONNECTED;
|
|
|
|
|
chopstx_mutex_init (&tty0.mtx);
|
|
|
|
|
chopstx_cond_init (&tty0.cnd);
|
|
|
|
|
tty0.inputline_len = 0;
|
|
|
|
|
tty0.send_head = tty0.send_tail = 0;
|
|
|
|
|
tty0.flag_connected = 0;
|
|
|
|
|
tty0.flag_send_ready = 1;
|
|
|
|
|
tty0.flag_input_avail = 0;
|
|
|
|
|
tty0.device_state = UNCONNECTED;
|
|
|
|
|
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
|
|
|
|
|
|
|
|
|
|
chopstx_create (PRIO_TTY, __stackaddr_tty, __stacksize_tty,
|
|
|
|
|
tty_main, NULL);
|
|
|
|
|
return &tty;
|
|
|
|
|
chopstx_create (PRIO_TTY, __stackaddr_tty, __stacksize_tty, tty_main, &tty0);
|
|
|
|
|
return &tty0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void *
|
|
|
|
|
tty_main (void *arg)
|
|
|
|
|
{
|
|
|
|
|
(void)arg;
|
|
|
|
|
struct tty *t = arg;
|
|
|
|
|
|
|
|
|
|
#if defined(OLDER_SYS_H)
|
|
|
|
|
/*
|
|
|
|
|
@@ -617,34 +670,34 @@ tty_main (void *arg)
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
usb_lld_init (VCOM_FEATURE_BUS_POWERED);
|
|
|
|
|
chopstx_claim_irq (&tty.intr, INTR_REQ_USB);
|
|
|
|
|
chopstx_claim_irq (&usb_intr, INTR_REQ_USB);
|
|
|
|
|
usb_interrupt_handler ();
|
|
|
|
|
#else
|
|
|
|
|
chopstx_claim_irq (&tty.intr, INTR_REQ_USB);
|
|
|
|
|
chopstx_claim_irq (&usb_intr, INTR_REQ_USB);
|
|
|
|
|
usb_lld_init (VCOM_FEATURE_BUS_POWERED);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
chopstx_poll (NULL, 1, &tty.intr);
|
|
|
|
|
if (tty.intr.ready)
|
|
|
|
|
chopstx_poll (NULL, 1, &usb_intr);
|
|
|
|
|
if (usb_intr.ready)
|
|
|
|
|
usb_interrupt_handler ();
|
|
|
|
|
|
|
|
|
|
chopstx_mutex_lock (&tty.mtx);
|
|
|
|
|
if (tty.device_state == CONFIGURED && tty.flag_connected
|
|
|
|
|
&& tty.flag_send_ready)
|
|
|
|
|
chopstx_mutex_lock (&t->mtx);
|
|
|
|
|
if (t->device_state == CONFIGURED && t->flag_connected
|
|
|
|
|
&& t->flag_send_ready)
|
|
|
|
|
{
|
|
|
|
|
uint8_t line[32];
|
|
|
|
|
int len = get_chars_from_ringbuffer (line, sizeof (len));
|
|
|
|
|
int len = get_chars_from_ringbuffer (t, line, sizeof (len));
|
|
|
|
|
|
|
|
|
|
if (len)
|
|
|
|
|
{
|
|
|
|
|
usb_lld_txcpy (line, ENDP1, 0, len);
|
|
|
|
|
usb_lld_tx_enable (ENDP1, len);
|
|
|
|
|
tty.flag_send_ready = 0;
|
|
|
|
|
t->flag_send_ready = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
chopstx_mutex_unlock (&tty.mtx);
|
|
|
|
|
chopstx_mutex_unlock (&t->mtx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|