Fix USB driver and example

This commit is contained in:
NIIBE Yutaka
2016-04-18 17:23:10 +09:00
parent 82749ab97a
commit 0bbb43dd3a
4 changed files with 136 additions and 17 deletions

View File

@@ -1,9 +1,20 @@
#include <stdint.h>
#include <stdlib.h>
#include <chopstx.h>
#include <string.h>
#include "usb_lld.h"
#include "stream.h"
static uint8_t send_buf[64];
static unsigned int send_len;
static uint8_t send_buf1[64];
static uint8_t recv_buf[64];
static unsigned int recv_len;
static uint8_t inputline[64];
static unsigned int inputline_len;
static struct stream stream;
#define USB_CDC_REQ_SET_LINE_CODING 0x20
@@ -184,6 +195,8 @@ usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, struct req_args *arg)
stream.flags &= ~FLAG_CONNECTED;
stream.flags |= ((arg->value & CDC_CTRL_DTR) != 0)? FLAG_CONNECTED : 0;
chopstx_cond_signal (&stream.cnd);
recv_len = 0;
usb_lld_rx_enable (ENDP3, recv_buf, 64);
chopstx_mutex_unlock (&stream.mtx);
}
}
@@ -389,21 +402,118 @@ usb_cb_interface (uint8_t cmd, struct req_args *arg)
}
static void
stream_echo_char (int c)
{
chopstx_mutex_lock (&stream.mtx);
if (send_len < sizeof (send_buf))
send_buf[send_len++] = c;
else
{
/* All that we can is ignoring the output. */
;
}
if (stream.sending == 0)
{
memcpy (send_buf1, send_buf, send_len);
usb_lld_tx_enable (ENDP1, send_buf1, send_len);
send_len = 0;
stream.sending = 1;
}
chopstx_mutex_unlock (&stream.mtx);
}
void
usb_cb_tx_done (uint8_t ep_num)
{
if (ep_num == ENDP1)
{
chopstx_mutex_lock (&stream.mtx);
if ((stream.flags & FLAG_SEND_AVAIL))
stream.sending = 0;
if (send_len)
{
stream.flags &= ~FLAG_SEND_AVAIL;
chopstx_cond_signal (&stream.cnd);
stream.sending = 1;
memcpy (send_buf1, send_buf, send_len);
usb_lld_tx_enable (ENDP1, send_buf1, send_len);
send_len = 0;
}
else
{
if ((stream.flags & FLAG_SEND_AVAIL))
{
stream.flags &= ~FLAG_SEND_AVAIL;
chopstx_cond_signal (&stream.cnd);
}
}
chopstx_mutex_unlock (&stream.mtx);
}
else if (ep_num == ENDP2)
{
/* Nothing */
}
}
static void
stream_input_char (int c)
{
unsigned int i;
/* Process DEL, C-U, C-R, and RET as editing command. */
switch (c)
{
case 0x0d: /* Control-M */
stream_echo_char (0x0d);
stream_echo_char (0x0a);
chopstx_mutex_lock (&stream.mtx);
if ((stream.flags & FLAG_RECV_AVAIL) == 0)
{
memcpy (stream.recv_buf, inputline, inputline_len);
stream.recv_len = inputline_len;
stream.flags |= FLAG_RECV_AVAIL;
chopstx_cond_signal (&stream.cnd);
}
chopstx_mutex_unlock (&stream.mtx);
inputline_len = 0;
break;
case 0x12: /* Control-R */
stream_echo_char ('^');
stream_echo_char ('R');
stream_echo_char (0x0d);
stream_echo_char (0x0a);
for (i = 0; i < inputline_len; i++)
stream_echo_char (inputline[i]);
break;
case 0x15: /* Control-U */
for (i = 0; i < inputline_len; i++)
{
stream_echo_char (0x08);
stream_echo_char (0x20);
stream_echo_char (0x08);
}
inputline_len = 0;
break;
case 0x7f: /* DEL */
if (inputline_len > 0)
{
stream_echo_char (0x08);
stream_echo_char (0x20);
stream_echo_char (0x08);
inputline_len--;
}
break;
default:
if (inputline_len < sizeof (inputline))
{
stream_echo_char (c);
inputline[inputline_len++] = c;
}
else
/* Beep */
stream_echo_char (0x0a);
break;
}
}
@@ -412,13 +522,13 @@ usb_cb_rx_ready (uint8_t ep_num)
{
if (ep_num == ENDP3)
{
chopstx_mutex_lock (&stream.mtx);
if ((stream.flags & FLAG_RECV_AVAIL) == 0)
{
stream.flags |= FLAG_RECV_AVAIL;
chopstx_cond_signal (&stream.cnd);
}
chopstx_mutex_unlock (&stream.mtx);
int i, r;
r = usb_lld_rx_data_len (ENDP3);
for (i = 0; i < r; i++)
stream_input_char (recv_buf[i]);
usb_lld_rx_enable (ENDP3, recv_buf, 64);
}
}
@@ -452,6 +562,7 @@ stream_send (struct stream *st, uint8_t *buf, uint8_t count)
r = -1;
else
{
stream.sending = 1;
usb_lld_tx_enable (ENDP1, buf, count);
stream.flags |= FLAG_SEND_AVAIL;
do
@@ -467,6 +578,7 @@ stream_send (struct stream *st, uint8_t *buf, uint8_t count)
}
while (1);
}
stream.sending = 0;
chopstx_mutex_unlock (&st->mtx);
return r;
}
@@ -482,14 +594,14 @@ stream_recv (struct stream *st, uint8_t *buf)
r = -1;
else
{
usb_lld_rx_enable (ENDP3, buf, 64);
stream.flags &= ~FLAG_RECV_AVAIL;
do
{
chopstx_cond_wait (&st->cnd, &st->mtx);
if ((stream.flags & FLAG_RECV_AVAIL))
{
r = usb_lld_rx_data_len (ENDP3);
r = stream.recv_len;
memcpy (buf, stream.recv_buf, r);
break;
}
else if ((stream.flags & FLAG_CONNECTED) == 0)