USB stack for STM32F103 improvement

This commit is contained in:
NIIBE Yutaka
2016-04-07 14:44:58 +09:00
parent 674c19c495
commit 92e17d3bdf
6 changed files with 93 additions and 87 deletions

View File

@@ -1,3 +1,14 @@
2016-04-07 Niibe Yutaka <gniibe@fsij.org>
* example-cdc/usb-cdc.c: Update.
* example-cdc/usb_stm32f103.c (usb_handle_transfer): Don't use
weak symbols for callbacks, but use explicit callbacks of
usb_cb_tx_done and usb_cb_rx_ready.
* example-cdc/usb_lld.h (usb_cb_tx_done, usb_cb_rx_ready): New
callbacks.
2016-04-07 Niibe Yutaka <gniibe@fsij.org> 2016-04-07 Niibe Yutaka <gniibe@fsij.org>
* chopstx.c (chx_cpu_sched_lock, chx_cpu_sched_unlock): Use SVC * chopstx.c (chx_cpu_sched_lock, chx_cpu_sched_unlock): Use SVC

View File

@@ -129,6 +129,7 @@ main (int argc, const char *argv[])
{ {
struct stream *st; struct stream *st;
uint8_t count; uint8_t count;
extern uint32_t bDeviceState;
(void)argc; (void)argc;
(void)argv; (void)argv;
@@ -153,11 +154,14 @@ main (int argc, const char *argv[])
chopstx_cond_signal (&cnd1); chopstx_cond_signal (&cnd1);
chopstx_mutex_unlock (&mtx); chopstx_mutex_unlock (&mtx);
count= 0; u = 1;
while (bDeviceState != CONFIGURED)
chopstx_usec_wait (500*1000);
count = 0;
while (1) while (1)
{ {
uint8_t s[64]; uint8_t s[64];
u = 1;
if (stream_wait_connection (st) < 0) if (stream_wait_connection (st) < 0)
{ {
@@ -165,6 +169,11 @@ main (int argc, const char *argv[])
continue; continue;
} }
chopstx_usec_wait (500*1000);
/* Send ZLP at the beginning. */
stream_send (st, s, 0);
memcpy (s, "xx: Hello, World with Chopstx!\r\n\000", 32); memcpy (s, "xx: Hello, World with Chopstx!\r\n\000", 32);
s[0] = hexchar (count >> 4); s[0] = hexchar (count >> 4);
s[1] = hexchar (count & 0x0f); s[1] = hexchar (count & 0x0f);
@@ -180,8 +189,11 @@ main (int argc, const char *argv[])
if (size < 0) if (size < 0)
break; break;
if (stream_send (st, s, size) < 0) if (size >= 0)
break; {
if (stream_send (st, s, size) < 0)
break;
}
u ^= 1; u ^= 1;
} }

View File

@@ -2,10 +2,10 @@
* ST32F103 memory setup. * ST32F103 memory setup.
*/ */
__main_stack_size__ = 0x0100; /* Exception handlers */ __main_stack_size__ = 0x0100; /* Exception handlers */
__process0_stack_size__ = 0x0100; /* Main program */ __process0_stack_size__ = 0x0200; /* Main program */
__process1_stack_size__ = 0x0100; /* first thread program */ __process1_stack_size__ = 0x0200; /* first thread program */
__process2_stack_size__ = 0x0100; /* second thread program */ __process2_stack_size__ = 0x0200; /* second thread program */
__process3_stack_size__ = 0x0100; /* third thread program */ __process3_stack_size__ = 0x0200; /* third thread program */
MEMORY MEMORY
{ {

View File

@@ -157,7 +157,7 @@ static const uint8_t vcom_string3[28] = {
#define NUM_INTERFACES 2 #define NUM_INTERFACES 2
static uint32_t bDeviceState = UNCONNECTED; /* USB device status */ uint32_t bDeviceState = UNCONNECTED; /* USB device status */
void void
@@ -400,35 +400,38 @@ usb_cb_interface (uint8_t cmd, struct req_args *arg)
void void
EP1_IN_Callback (void) usb_cb_tx_done (uint8_t ep_num)
{ {
chopstx_mutex_lock (&stream.mtx); if (ep_num == ENDP1)
if ((stream.flags & FLAG_SEND_AVAIL)) {
chopstx_mutex_lock (&stream.mtx);
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)
{ {
stream.flags &= ~FLAG_SEND_AVAIL;
chopstx_cond_signal (&stream.cnd);
} }
chopstx_mutex_unlock (&stream.mtx);
} }
void void
EP2_IN_Callback (void) usb_cb_rx_ready (uint8_t ep_num)
{ {
} if (ep_num == ENDP3)
void
EP3_OUT_Callback (void)
{
chopstx_mutex_lock (&stream.mtx);
if ((stream.flags & FLAG_RECV_AVAIL) == 0)
{ {
stream.flags |= FLAG_RECV_AVAIL; chopstx_mutex_lock (&stream.mtx);
chopstx_cond_signal (&stream.cnd); if ((stream.flags & FLAG_RECV_AVAIL) == 0)
{
stream.flags |= FLAG_RECV_AVAIL;
chopstx_cond_signal (&stream.cnd);
}
chopstx_mutex_unlock (&stream.mtx);
} }
chopstx_mutex_unlock (&stream.mtx);
} }
struct stream * struct stream *
stream_open (void) stream_open (void)
{ {
@@ -441,7 +444,7 @@ int
stream_wait_connection (struct stream *st) stream_wait_connection (struct stream *st)
{ {
chopstx_mutex_lock (&st->mtx); chopstx_mutex_lock (&st->mtx);
if ((stream.flags & FLAG_CONNECTED) == 0) while ((stream.flags & FLAG_CONNECTED) == 0)
chopstx_cond_wait (&st->cnd, &st->mtx); chopstx_cond_wait (&st->cnd, &st->mtx);
chopstx_mutex_unlock (&st->mtx); chopstx_mutex_unlock (&st->mtx);
stream.flags &= ~FLAG_SEND_AVAIL; stream.flags &= ~FLAG_SEND_AVAIL;
@@ -452,46 +455,63 @@ stream_wait_connection (struct stream *st)
int int
stream_send (struct stream *st, uint8_t *buf, uint8_t count) stream_send (struct stream *st, uint8_t *buf, uint8_t count)
{ {
int r = 0;
chopstx_mutex_lock (&st->mtx); chopstx_mutex_lock (&st->mtx);
if ((stream.flags & FLAG_CONNECTED) == 0) if ((stream.flags & FLAG_CONNECTED) == 0)
{ r = -1;
chopstx_mutex_unlock (&st->mtx);
return -1;
}
else else
{ {
usb_lld_write (ENDP1, buf, count); usb_lld_write (ENDP1, buf, count);
stream.flags |= FLAG_SEND_AVAIL; stream.flags |= FLAG_SEND_AVAIL;
while ((stream.flags & FLAG_SEND_AVAIL)) do
chopstx_cond_wait (&st->cnd, &st->mtx); {
chopstx_cond_wait (&st->cnd, &st->mtx);
if ((stream.flags & FLAG_SEND_AVAIL) == 0)
break;
else if ((stream.flags & FLAG_CONNECTED) == 0)
{
r = -1;
break;
}
}
while (1);
} }
chopstx_mutex_unlock (&st->mtx); chopstx_mutex_unlock (&st->mtx);
return 0; return r;
} }
int int
stream_recv (struct stream *st, uint8_t *buf) stream_recv (struct stream *st, uint8_t *buf)
{ {
int recv_size; int r;
chopstx_mutex_lock (&st->mtx); chopstx_mutex_lock (&st->mtx);
if ((stream.flags & FLAG_CONNECTED) == 0) if ((stream.flags & FLAG_CONNECTED) == 0)
{ r = -1;
chopstx_mutex_unlock (&st->mtx);
return -1;
}
else else
{ {
usb_lld_rx_enable (ENDP3); usb_lld_rx_enable (ENDP3);
stream.flags &= ~FLAG_RECV_AVAIL; stream.flags &= ~FLAG_RECV_AVAIL;
while ((stream.flags & FLAG_RECV_AVAIL) == 0) do
chopstx_cond_wait (&st->cnd, &st->mtx); {
chopstx_cond_wait (&st->cnd, &st->mtx);
recv_size = usb_lld_rx_data_len (ENDP3); if ((stream.flags & FLAG_RECV_AVAIL))
usb_lld_rxcpy (buf, ENDP3, 0, recv_size); {
r = usb_lld_rx_data_len (ENDP3);
usb_lld_rxcpy (buf, ENDP3, 0, r);
break;
}
else if ((stream.flags & FLAG_CONNECTED) == 0)
{
r = -1;
break;
}
}
while (1);
} }
chopstx_mutex_unlock (&st->mtx); chopstx_mutex_unlock (&st->mtx);
return recv_size; return r;
} }

View File

@@ -63,6 +63,8 @@ int usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
int usb_cb_handle_event (uint8_t event_type, uint16_t value); int usb_cb_handle_event (uint8_t event_type, uint16_t value);
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no,
struct req_args *arg); struct req_args *arg);
void usb_cb_tx_done (uint8_t ep_num);
void usb_cb_rx_ready (uint8_t ep_num);
enum { enum {
USB_EVENT_ADDRESS, USB_EVENT_ADDRESS,

View File

@@ -843,27 +843,6 @@ static void handle_out0 (void)
dev_p->state = STALLED; dev_p->state = STALLED;
} }
static void nop_proc (void)
{
}
#define WEAK __attribute__ ((weak, alias ("nop_proc")))
void WEAK EP1_IN_Callback (void);
void WEAK EP2_IN_Callback (void);
void WEAK EP3_IN_Callback (void);
void WEAK EP4_IN_Callback (void);
void WEAK EP5_IN_Callback (void);
void WEAK EP6_IN_Callback (void);
void WEAK EP7_IN_Callback (void);
void WEAK EP1_OUT_Callback (void);
void WEAK EP2_OUT_Callback (void);
void WEAK EP3_OUT_Callback (void);
void WEAK EP4_OUT_Callback (void);
void WEAK EP5_OUT_Callback (void);
void WEAK EP6_OUT_Callback (void);
void WEAK EP7_OUT_Callback (void);
static void static void
usb_handle_transfer (uint16_t istr_value) usb_handle_transfer (uint16_t istr_value)
{ {
@@ -901,31 +880,13 @@ usb_handle_transfer (uint16_t istr_value)
if ((ep_value & EP_CTR_RX)) if ((ep_value & EP_CTR_RX))
{ {
st103_ep_clear_ctr_rx (ep_index); st103_ep_clear_ctr_rx (ep_index);
switch ((ep_index - 1)) usb_cb_rx_ready (ep_index);
{
case 0: EP1_OUT_Callback (); break;
case 1: EP2_OUT_Callback (); break;
case 2: EP3_OUT_Callback (); break;
case 3: EP4_OUT_Callback (); break;
case 4: EP5_OUT_Callback (); break;
case 5: EP6_OUT_Callback (); break;
case 6: EP7_OUT_Callback (); break;
}
} }
if ((ep_value & EP_CTR_TX)) if ((ep_value & EP_CTR_TX))
{ {
st103_ep_clear_ctr_tx (ep_index); st103_ep_clear_ctr_tx (ep_index);
switch ((ep_index - 1)) usb_cb_tx_done (ep_index);
{
case 0: EP1_IN_Callback (); break;
case 1: EP2_IN_Callback (); break;
case 2: EP3_IN_Callback (); break;
case 3: EP4_IN_Callback (); break;
case 4: EP5_IN_Callback (); break;
case 5: EP6_IN_Callback (); break;
case 6: EP7_IN_Callback (); break;
}
} }
} }
} }