USB-USART config setup support.

This commit is contained in:
NIIBE Yutaka
2017-12-17 11:52:17 +09:00
parent 0e9737eb61
commit 1533284ace
2 changed files with 90 additions and 10 deletions

View File

@@ -5,5 +5,12 @@ ST-Link/V2 is disconnected (SB13 and SB14).
TODO: TODO:
* serial config setting * serial config setting
* CTSRTS? How by USB? By vendor specific control?
* stats report control * stats report control
* USB communication class interface notification (interrupt ENDP2) support
SERIAL_STATE
* SEND_BREAK support
* Use of DMA for serial communication * Use of DMA for serial communication
* RS-232 support: GPIO with DTR (out), DCD (in), DSR (in), RI (in)
* Half-duplex support
* Support of other communication mode: smartcard, IrDA, etc.

View File

@@ -2,7 +2,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <chopstx.h> #include <chopstx.h>
#include <string.h> #include <string.h>
#include "usb_lld.h" #include <contrib/usart.h>
#include <usb_lld.h>
#include "cdc.h" #include "cdc.h"
static chopstx_intr_t usb_intr; static chopstx_intr_t usb_intr;
@@ -12,7 +13,7 @@ struct line_coding
uint32_t bitrate; uint32_t bitrate;
uint8_t format; uint8_t format;
uint8_t paritytype; uint8_t paritytype;
uint8_t datatype; uint8_t databits;
} __attribute__((packed)); } __attribute__((packed));
static const struct line_coding lc_default = { static const struct line_coding lc_default = {
@@ -25,6 +26,8 @@ static const struct line_coding lc_default = {
static uint8_t device_state; /* USB device status */ static uint8_t device_state; /* USB device status */
struct cdc { struct cdc {
uint8_t dev_no;
uint8_t endp1; uint8_t endp1;
uint8_t endp2; uint8_t endp2;
uint8_t endp3; uint8_t endp3;
@@ -333,6 +336,71 @@ usb_device_reset (struct usb_dev *dev)
} }
static void
setup_usart_config (struct cdc *s)
{
/* Check supported config(s) */
uint32_t config_bits;
if (s->line_coding.bitrate == 9600)
config_bits = B9600;
else if (s->line_coding.bitrate == 19200)
config_bits = B19200;
else if (s->line_coding.bitrate == 57600)
config_bits = B57600;
else if (s->line_coding.bitrate == 115200)
config_bits = B115200;
else
{
s->line_coding.bitrate = 115200;
config_bits = B115200;
}
if (s->line_coding.format == 0)
config_bits |= STOP1B;
else if (s->line_coding.format == 1)
config_bits |= STOP1B5;
else if (s->line_coding.format == 2)
config_bits |= STOP2B;
else
{
s->line_coding.format = 0;
config_bits |= STOP1B;
}
if (s->line_coding.paritytype == 0)
config_bits |= 0;
else if (s->line_coding.paritytype == 1)
config_bits |= (PARENB | PARODD);
else if (s->line_coding.paritytype == 2)
config_bits |= PARENB;
else
{
s->line_coding.paritytype = 0;
config_bits |= 0;
}
if (s->line_coding.databits == 7)
config_bits |= CS7;
else if (s->line_coding.databits == 7)
config_bits |= CS8;
else
{
s->line_coding.databits = 8;
config_bits |= CS8;
}
if (s->line_coding.databits == 7 && s->line_coding.paritytype == 0)
{
s->line_coding.databits = 8;
config_bits &= ~MASK_CS;
config_bits |= CS8;
}
usart_config (s->dev_no, config_bits);
}
#define CDC_CTRL_DTR 0x0001 #define CDC_CTRL_DTR 0x0001
static void static void
@@ -342,18 +410,21 @@ usb_ctrl_write_finish (struct usb_dev *dev)
uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT); uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT);
if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT) if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT)
&& USB_SETUP_SET (arg->type) && USB_SETUP_SET (arg->type))
&& arg->request == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
{ {
struct cdc *s = cdc_get (arg->index, 0); struct cdc *s = cdc_get (arg->index, 0);
/* Open/close the connection. */ if (arg->request == USB_CDC_REQ_SET_LINE_CODING)
chopstx_mutex_lock (&s->mtx); setup_usart_config (s);
s->flag_connected = ((arg->value & CDC_CTRL_DTR) != 0); else if (arg->request == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
chopstx_cond_broadcast (&s->cnd_rx); {
chopstx_mutex_unlock (&s->mtx); /* Open/close the connection. */
chopstx_mutex_lock (&s->mtx);
s->flag_connected = ((arg->value & CDC_CTRL_DTR) != 0);
chopstx_cond_broadcast (&s->cnd_rx);
chopstx_mutex_unlock (&s->mtx);
}
} }
/* /*
* The transaction was already finished. So, it is no use to call * The transaction was already finished. So, it is no use to call
* usb_lld_ctrl_error when the condition does not match. * usb_lld_ctrl_error when the condition does not match.
@@ -660,12 +731,14 @@ cdc_init (void)
if (i == 0) if (i == 0)
{ {
s->dev_no = 2;
s->endp1 = ENDP1; s->endp1 = ENDP1;
s->endp2 = ENDP2; s->endp2 = ENDP2;
s->endp3 = ENDP3; s->endp3 = ENDP3;
} }
else else
{ {
s->dev_no = 3;
s->endp1 = ENDP4; s->endp1 = ENDP4;
s->endp2 = ENDP5; s->endp2 = ENDP5;
s->endp3 = ENDP6; s->endp3 = ENDP6;