CDC to be echo service.
This commit is contained in:
@@ -1,3 +1,7 @@
|
|||||||
|
2015-11-05 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* example-cdc/sample.c: Enhanced to be echo service.
|
||||||
|
|
||||||
2015-09-15 Niibe Yutaka <gniibe@fsij.org>
|
2015-09-15 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
* VERSION: 0.10.
|
* VERSION: 0.10.
|
||||||
|
|||||||
@@ -3,14 +3,13 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <chopstx.h>
|
#include <chopstx.h>
|
||||||
#include "sys.h" /* for set_led */
|
#include "sys.h" /* for set_led */
|
||||||
#include "usb_lld.h" /* for set_led */
|
#include "usb_lld.h"
|
||||||
|
#include "stream.h"
|
||||||
|
|
||||||
static chopstx_mutex_t mtx;
|
static chopstx_mutex_t mtx;
|
||||||
static chopstx_cond_t cnd0;
|
static chopstx_cond_t cnd0;
|
||||||
static chopstx_cond_t cnd1;
|
static chopstx_cond_t cnd1;
|
||||||
|
|
||||||
chopstx_mutex_t usb_mtx;
|
|
||||||
chopstx_cond_t cnd_usb;
|
|
||||||
|
|
||||||
static uint8_t u, v;
|
static uint8_t u, v;
|
||||||
static uint8_t m; /* 0..100 */
|
static uint8_t m; /* 0..100 */
|
||||||
@@ -128,6 +127,7 @@ static char hexchar (uint8_t x)
|
|||||||
int
|
int
|
||||||
main (int argc, const char *argv[])
|
main (int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
|
struct stream *st;
|
||||||
uint8_t count;
|
uint8_t count;
|
||||||
|
|
||||||
(void)argc;
|
(void)argc;
|
||||||
@@ -137,8 +137,7 @@ main (int argc, const char *argv[])
|
|||||||
chopstx_cond_init (&cnd0);
|
chopstx_cond_init (&cnd0);
|
||||||
chopstx_cond_init (&cnd1);
|
chopstx_cond_init (&cnd1);
|
||||||
|
|
||||||
chopstx_mutex_init (&usb_mtx);
|
st = stream_open ();
|
||||||
chopstx_cond_init (&cnd_usb);
|
|
||||||
|
|
||||||
m = 10;
|
m = 10;
|
||||||
|
|
||||||
@@ -154,41 +153,38 @@ main (int argc, const char *argv[])
|
|||||||
chopstx_cond_signal (&cnd1);
|
chopstx_cond_signal (&cnd1);
|
||||||
chopstx_mutex_unlock (&mtx);
|
chopstx_mutex_unlock (&mtx);
|
||||||
|
|
||||||
|
count= 0;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
extern uint8_t connected;
|
uint8_t s[64];
|
||||||
|
|
||||||
count= 0;
|
|
||||||
u = 1;
|
u = 1;
|
||||||
/* waiting USB connection */
|
|
||||||
chopstx_mutex_lock (&usb_mtx);
|
if (stream_wait_connection (st) < 0)
|
||||||
if (!connected)
|
{
|
||||||
chopstx_cond_wait (&cnd_usb, &usb_mtx);
|
chopstx_usec_wait (1000*1000);
|
||||||
chopstx_mutex_unlock (&usb_mtx);
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (s, "xx: Hello, World with Chopstx!\r\n\000", 32);
|
||||||
|
s[0] = hexchar (count >> 4);
|
||||||
|
s[1] = hexchar (count & 0x0f);
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (stream_send (st, s, 32) < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
char s[32];
|
int size = stream_recv (st, s);
|
||||||
|
|
||||||
|
if (size < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (stream_send (st, s, size) < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
u ^= 1;
|
u ^= 1;
|
||||||
chopstx_usec_wait (200*1000*6);
|
|
||||||
|
|
||||||
memcpy (s, "xx: Hello, World with Chopstx!\r\n", 32);
|
|
||||||
s[0] = hexchar (count >> 4);
|
|
||||||
s[1] = hexchar (count & 0x0f);
|
|
||||||
count++;
|
|
||||||
|
|
||||||
chopstx_mutex_lock (&usb_mtx);
|
|
||||||
if (connected)
|
|
||||||
{
|
|
||||||
usb_lld_write (ENDP1, s, 32);
|
|
||||||
chopstx_cond_wait (&cnd_usb, &usb_mtx);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
chopstx_mutex_unlock (&usb_mtx);
|
|
||||||
}
|
}
|
||||||
chopstx_mutex_unlock (&usb_mtx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
24
example-cdc/stream.h
Normal file
24
example-cdc/stream.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#define BUFSIZE 128
|
||||||
|
#define FLAG_CONNECTED (1 << 0)
|
||||||
|
#define FLAG_SEND_AVAIL (1 << 1)
|
||||||
|
#define FLAG_RECV_AVAIL (1 << 2)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Current implementation is synchronous and buffers are not yet used.
|
||||||
|
*/
|
||||||
|
struct stream {
|
||||||
|
chopstx_mutex_t mtx;
|
||||||
|
chopstx_cond_t cnd;
|
||||||
|
uint8_t buf_send[BUFSIZE]; /* Not yet used. */
|
||||||
|
uint8_t buf_recv[BUFSIZE]; /* Not yet used. */
|
||||||
|
uint8_t cnt_send_head; /* Not yet used. */
|
||||||
|
uint8_t cnt_send_tail; /* Not yet used. */
|
||||||
|
uint8_t cnt_recv_head; /* Not yet used. */
|
||||||
|
uint8_t cnt_recv_tail; /* Not yet used. */
|
||||||
|
uint32_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct stream *stream_open (void);
|
||||||
|
int stream_wait_connection (struct stream *st);
|
||||||
|
int stream_send (struct stream *st, uint8_t *buf, uint8_t count);
|
||||||
|
int stream_recv (struct stream *st, uint8_t *buf);
|
||||||
@@ -2,9 +2,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <chopstx.h>
|
#include <chopstx.h>
|
||||||
#include "usb_lld.h"
|
#include "usb_lld.h"
|
||||||
|
#include "stream.h"
|
||||||
|
|
||||||
extern chopstx_mutex_t usb_mtx;
|
static struct stream stream;
|
||||||
extern chopstx_cond_t cnd_usb;
|
|
||||||
|
|
||||||
#define ENDP0_RXADDR (0x40)
|
#define ENDP0_RXADDR (0x40)
|
||||||
#define ENDP0_TXADDR (0x80)
|
#define ENDP0_TXADDR (0x80)
|
||||||
@@ -157,8 +157,8 @@ static const uint8_t vcom_string3[28] = {
|
|||||||
|
|
||||||
#define NUM_INTERFACES 2
|
#define NUM_INTERFACES 2
|
||||||
|
|
||||||
uint32_t bDeviceState = UNCONNECTED; /* USB device status */
|
static uint32_t bDeviceState = UNCONNECTED; /* USB device status */
|
||||||
uint8_t connected;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
usb_cb_device_reset (void)
|
usb_cb_device_reset (void)
|
||||||
@@ -174,11 +174,10 @@ usb_cb_device_reset (void)
|
|||||||
/* Initialize Endpoint 0 */
|
/* Initialize Endpoint 0 */
|
||||||
usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR, 64);
|
usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR, 64);
|
||||||
|
|
||||||
chopstx_mutex_lock (&usb_mtx);
|
chopstx_mutex_lock (&stream.mtx);
|
||||||
connected = 0;
|
stream.flags = 0;
|
||||||
bDeviceState = ATTACHED;
|
bDeviceState = ATTACHED;
|
||||||
chopstx_cond_signal (&cnd_usb);
|
chopstx_mutex_unlock (&stream.mtx);
|
||||||
chopstx_mutex_unlock (&usb_mtx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -193,10 +192,11 @@ usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value)
|
|||||||
&& USB_SETUP_SET (req) && req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
|
&& USB_SETUP_SET (req) && req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
|
||||||
{
|
{
|
||||||
/* Open/close the connection. */
|
/* Open/close the connection. */
|
||||||
chopstx_mutex_lock (&usb_mtx);
|
chopstx_mutex_lock (&stream.mtx);
|
||||||
connected = ((value & CDC_CTRL_DTR) != 0)? 1 : 0;
|
stream.flags &= ~FLAG_CONNECTED;
|
||||||
chopstx_cond_signal (&cnd_usb);
|
stream.flags |= ((value & CDC_CTRL_DTR) != 0)? FLAG_CONNECTED : 0;
|
||||||
chopstx_mutex_unlock (&usb_mtx);
|
chopstx_cond_signal (&stream.cnd);
|
||||||
|
chopstx_mutex_unlock (&stream.mtx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,6 +312,8 @@ vcom_setup_endpoints_for_interface (uint16_t interface, int stop)
|
|||||||
{
|
{
|
||||||
usb_lld_setup_endpoint (ENDP1, EP_BULK, 0, 0, ENDP1_TXADDR, 0);
|
usb_lld_setup_endpoint (ENDP1, EP_BULK, 0, 0, ENDP1_TXADDR, 0);
|
||||||
usb_lld_setup_endpoint (ENDP3, EP_BULK, 0, ENDP3_RXADDR, 0, 64);
|
usb_lld_setup_endpoint (ENDP3, EP_BULK, 0, ENDP3_RXADDR, 0, 64);
|
||||||
|
/* Start with no data receiving */
|
||||||
|
usb_lld_stall_rx (ENDP3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -321,7 +323,8 @@ vcom_setup_endpoints_for_interface (uint16_t interface, int stop)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int usb_cb_handle_event (uint8_t event_type, uint16_t value)
|
int
|
||||||
|
usb_cb_handle_event (uint8_t event_type, uint16_t value)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uint8_t current_conf;
|
uint8_t current_conf;
|
||||||
@@ -365,7 +368,8 @@ int usb_cb_handle_event (uint8_t event_type, uint16_t value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int usb_cb_interface (uint8_t cmd, struct control_info *detail)
|
int
|
||||||
|
usb_cb_interface (uint8_t cmd, struct control_info *detail)
|
||||||
{
|
{
|
||||||
const uint8_t zero = 0;
|
const uint8_t zero = 0;
|
||||||
uint16_t interface = detail->index;
|
uint16_t interface = detail->index;
|
||||||
@@ -394,12 +398,17 @@ int usb_cb_interface (uint8_t cmd, struct control_info *detail)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EP1_IN_Callback (void)
|
EP1_IN_Callback (void)
|
||||||
{
|
{
|
||||||
chopstx_mutex_lock (&usb_mtx);
|
chopstx_mutex_lock (&stream.mtx);
|
||||||
chopstx_cond_signal (&cnd_usb);
|
if ((stream.flags & FLAG_SEND_AVAIL))
|
||||||
chopstx_mutex_unlock (&usb_mtx);
|
{
|
||||||
|
stream.flags &= ~FLAG_SEND_AVAIL;
|
||||||
|
chopstx_cond_signal (&stream.cnd);
|
||||||
|
}
|
||||||
|
chopstx_mutex_unlock (&stream.mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -410,5 +419,79 @@ EP2_IN_Callback (void)
|
|||||||
void
|
void
|
||||||
EP3_OUT_Callback (void)
|
EP3_OUT_Callback (void)
|
||||||
{
|
{
|
||||||
usb_lld_rx_enable (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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct stream *
|
||||||
|
stream_open (void)
|
||||||
|
{
|
||||||
|
chopstx_mutex_init (&stream.mtx);
|
||||||
|
chopstx_cond_init (&stream.cnd);
|
||||||
|
return &stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
stream_wait_connection (struct stream *st)
|
||||||
|
{
|
||||||
|
chopstx_mutex_lock (&st->mtx);
|
||||||
|
if ((stream.flags & FLAG_CONNECTED) == 0)
|
||||||
|
chopstx_cond_wait (&st->cnd, &st->mtx);
|
||||||
|
chopstx_mutex_unlock (&st->mtx);
|
||||||
|
stream.flags &= ~FLAG_SEND_AVAIL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
stream_send (struct stream *st, uint8_t *buf, uint8_t count)
|
||||||
|
{
|
||||||
|
chopstx_mutex_lock (&st->mtx);
|
||||||
|
if ((stream.flags & FLAG_CONNECTED) == 0)
|
||||||
|
{
|
||||||
|
chopstx_mutex_unlock (&st->mtx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usb_lld_write (ENDP1, buf, count);
|
||||||
|
stream.flags |= FLAG_SEND_AVAIL;
|
||||||
|
while ((stream.flags & FLAG_SEND_AVAIL))
|
||||||
|
chopstx_cond_wait (&st->cnd, &st->mtx);
|
||||||
|
}
|
||||||
|
chopstx_mutex_unlock (&st->mtx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
stream_recv (struct stream *st, uint8_t *buf)
|
||||||
|
{
|
||||||
|
int recv_size;
|
||||||
|
|
||||||
|
chopstx_mutex_lock (&st->mtx);
|
||||||
|
if ((stream.flags & FLAG_CONNECTED) == 0)
|
||||||
|
{
|
||||||
|
chopstx_mutex_unlock (&st->mtx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usb_lld_rx_enable (ENDP3);
|
||||||
|
stream.flags &= ~FLAG_RECV_AVAIL;
|
||||||
|
while ((stream.flags & FLAG_RECV_AVAIL) == 0)
|
||||||
|
chopstx_cond_wait (&st->cnd, &st->mtx);
|
||||||
|
|
||||||
|
recv_size = usb_lld_rx_data_len (ENDP3);
|
||||||
|
usb_lld_rxcpy (buf, ENDP3, 0, recv_size);
|
||||||
|
}
|
||||||
|
chopstx_mutex_unlock (&st->mtx);
|
||||||
|
|
||||||
|
return recv_size;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user