summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2017-07-09 05:10:35 +0200
committerChristian Pointner <equinox@spreadspace.org>2017-07-09 05:10:35 +0200
commitb2416621ebe7feaac96166f9576d3d34cffd4de4 (patch)
tree0730e8998fcc93b5e17a7846ab7c5649e5548b6e
parentusbconfig.h for CDC-ACM (diff)
vusb cdc-acm example (still not working)
-rw-r--r--vusb-led/Makefile2
-rw-r--r--vusb-led/usbconfig.h5
-rw-r--r--vusb-led/vusb-led.c264
3 files changed, 254 insertions, 17 deletions
diff --git a/vusb-led/Makefile b/vusb-led/Makefile
index 7f8af33..e505dc2 100644
--- a/vusb-led/Makefile
+++ b/vusb-led/Makefile
@@ -20,7 +20,7 @@
## along with spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
##
-NAME := usb-led
+NAME := vusb-led
BOARD_TYPE := digispark
OBJ := $(NAME).o
LIBS := util led
diff --git a/vusb-led/usbconfig.h b/vusb-led/usbconfig.h
index a54a189..a111c69 100644
--- a/vusb-led/usbconfig.h
+++ b/vusb-led/usbconfig.h
@@ -58,12 +58,7 @@
* #define USB_SOF_HOOK myAssemblerMacro
*/
#define USB_CFG_CHECK_DATA_TOGGLING 0
-#if USB_CFG_CLOCK_KHZ==16500 || USB_CFG_CLOCK_KHZ==12800
-#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 1
-#include "osccal.h"
-#else
#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
-#endif
#define USB_USE_FAST_CRC 0
/* -------------------------- Device Description --------------------------- */
diff --git a/vusb-led/vusb-led.c b/vusb-led/vusb-led.c
index 6818c8a..d47d415 100644
--- a/vusb-led/vusb-led.c
+++ b/vusb-led/vusb-led.c
@@ -25,11 +25,229 @@
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <avr/power.h>
+#include <util/delay.h>
#include <stdio.h>
+#include "usbdrv.h"
+#include "oddebug.h"
+
#include "util.h"
#include "led.h"
+
+enum {
+ SEND_ENCAPSULATED_COMMAND = 0,
+ GET_ENCAPSULATED_RESPONSE,
+ SET_COMM_FEATURE,
+ GET_COMM_FEATURE,
+ CLEAR_COMM_FEATURE,
+ SET_LINE_CODING = 0x20,
+ GET_LINE_CODING,
+ SET_CONTROL_LINE_STATE,
+ SEND_BREAK
+};
+
+#define VUSBIO_BULK_OUT_SIZE 8
+#define VUSBIO_BULK_IN_SIZE 8
+
+static PROGMEM const char configDescrCDC[] = { /* USB configuration descriptor */
+ 9, /* sizeof(usbDescrConfig): length of descriptor in bytes */
+ USBDESCR_CONFIG, /* descriptor type */
+ 67,
+ 0, /* total length of data returned (including inlined descriptors) */
+ 2, /* number of interfaces in this configuration */
+ 1, /* index of this configuration */
+ 0, /* configuration name string index */
+#if USB_CFG_IS_SELF_POWERED
+ (1 << 7) | USBATTR_SELFPOWER, /* attributes */
+#else
+ (1 << 7), /* attributes */
+#endif
+ USB_CFG_MAX_BUS_POWER/2, /* max USB current in 2mA units */
+
+ /* interface descriptor follows inline: */
+ 9, /* sizeof(usbDescrInterface): length of descriptor in bytes */
+ USBDESCR_INTERFACE, /* descriptor type */
+ 0, /* index of this interface */
+ 0, /* alternate setting for this interface */
+ USB_CFG_HAVE_INTRIN_ENDPOINT, /* endpoints excl 0: number of endpoint descriptors to follow */
+ USB_CFG_INTERFACE_CLASS,
+ USB_CFG_INTERFACE_SUBCLASS,
+ USB_CFG_INTERFACE_PROTOCOL,
+ 0, /* string index for interface */
+
+ /* CDC Class-Specific descriptor */
+ 5, /* sizeof(usbDescrCDC_HeaderFn): length of descriptor in bytes */
+ 0x24, /* descriptor type */
+ 0, /* header functional descriptor */
+ 0x10, 0x01,
+
+ 4, /* sizeof(usbDescrCDC_AcmFn): length of descriptor in bytes */
+ 0x24, /* descriptor type */
+ 2, /* abstract control management functional descriptor */
+ 0x02, /* SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE */
+
+ 5, /* sizeof(usbDescrCDC_UnionFn): length of descriptor in bytes */
+ 0x24, /* descriptor type */
+ 6, /* union functional descriptor */
+ 0, /* CDC_COMM_INTF_ID */
+ 1, /* CDC_DATA_INTF_ID */
+
+ 5, /* sizeof(usbDescrCDC_CallMgtFn): length of descriptor in bytes */
+ 0x24, /* descriptor type */
+ 1, /* call management functional descriptor */
+ 3, /* allow management on data interface, handles call management by itself */
+ 1, /* CDC_DATA_INTF_ID */
+
+ /* Endpoint Descriptor */
+ 7, /* sizeof(usbDescrEndpoint) */
+ USBDESCR_ENDPOINT, /* descriptor type = endpoint */
+ 0x80|USB_CFG_EP3_NUMBER, /* IN endpoint number 3 */
+ 0x03, /* attrib: Interrupt endpoint */
+ 8, 0, /* maximum packet size */
+ USB_CFG_INTR_POLL_INTERVAL, /* in ms */
+
+ /* Interface Descriptor */
+ 9, /* sizeof(usbDescrInterface): length of descriptor in bytes */
+ USBDESCR_INTERFACE, /* descriptor type */
+ 1, /* index of this interface */
+ 0, /* alternate setting for this interface */
+ 2, /* endpoints excl 0: number of endpoint descriptors to follow */
+ 0x0A, /* Data Interface Class Codes */
+ 0,
+ 0, /* Data Interface Class Protocol Codes */
+ 0, /* string index for interface */
+
+ /* Endpoint Descriptor */
+ 7, /* sizeof(usbDescrEndpoint) */
+ USBDESCR_ENDPOINT, /* descriptor type = endpoint */
+ 0x01, /* OUT endpoint number 1 */
+ 0x02, /* attrib: Bulk endpoint */
+ VUSBIO_BULK_OUT_SIZE, 0, /* maximum packet size */
+ 0, /* in ms */
+
+ /* Endpoint Descriptor */
+ 7, /* sizeof(usbDescrEndpoint) */
+ USBDESCR_ENDPOINT, /* descriptor type = endpoint */
+ 0x81, /* IN endpoint number 1 */
+ 0x02, /* attrib: Bulk endpoint */
+ VUSBIO_BULK_IN_SIZE, 0, /* maximum packet size */
+ 0, /* in ms */
+};
+
+
+uchar usbFunctionDescriptor(usbRequest_t *rq)
+{
+ if(rq->wValue.bytes[1] == USBDESCR_DEVICE) {
+ usbMsgPtr = (uchar *)usbDescriptorDevice;
+ return usbDescriptorDevice[0];
+ } else { /* must be config descriptor */
+ usbMsgPtr = (uchar *)configDescrCDC;
+ return sizeof(configDescrCDC);
+ }
+}
+
+
+uchar sendEmptyFrame;
+static uchar intr3Status; /* used to control interrupt endpoint transmissions */
+static usbWord_t baud;
+
+
+/* ------------------------------------------------------------------------- */
+/* ----------------------------- USB interface ----------------------------- */
+/* ------------------------------------------------------------------------- */
+
+uchar usbFunctionSetup(uchar data[8])
+{
+ usbRequest_t *rq = (void *)data;
+
+ if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */
+ if( rq->bRequest==GET_LINE_CODING || rq->bRequest==SET_LINE_CODING ) {
+ return 0xff;
+ /* GET_LINE_CODING -> usbFunctionRead() */
+ /* SET_LINE_CODING -> usbFunctionWrite() */
+ }
+ if(rq->bRequest == SET_CONTROL_LINE_STATE) {
+ /* Report serial state (carrier detect). On several Unix platforms,
+ * tty devices can only be opened when carrier detect is set.
+ */
+ if(intr3Status==0)
+ intr3Status = 2;
+ }
+
+ /* Prepare bulk-in endpoint to respond to early termination */
+ if((rq->bmRequestType & USBRQ_DIR_MASK) == USBRQ_DIR_HOST_TO_DEVICE)
+ sendEmptyFrame = 1;
+ }
+
+ return 0;
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* usbFunctionRead */
+/*---------------------------------------------------------------------------*/
+
+uchar usbFunctionRead(uchar *data, uchar len)
+{
+ data[0] = baud.bytes[0];
+ data[1] = baud.bytes[1];
+ data[2] = 0;
+ data[3] = 0;
+ data[4] = 0;
+ data[5] = 0;
+ data[6] = 8;
+
+ return 7;
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* usbFunctionWrite */
+/*---------------------------------------------------------------------------*/
+
+uchar usbFunctionWrite(uchar *data, uchar len)
+{
+ /* SET_LINE_CODING */
+ baud.bytes[0] = data[0];
+ baud.bytes[1] = data[1];
+
+ //uartInit(baud.word);
+ return 1;
+}
+
+void usbFunctionWriteOut(uchar *data, uchar len)
+{
+ for(;len;len--) {
+// tx_buf[uwptr++] = *data++;
+ }
+}
+
+static void vusbio_init(void)
+{
+ /* activate pull-ups except on USB lines */
+ USB_CFG_IOPORT = (uchar)~((1<<USB_CFG_DMINUS_BIT)|(1<<USB_CFG_DPLUS_BIT));
+ /* all pins input except USB (-> USB reset) */
+#ifdef USB_CFG_PULLUP_IOPORT /* use usbDeviceConnect()/usbDeviceDisconnect() if available */
+ USBDDR = 0; /* we do RESET by deactivating pullup */
+ usbDeviceDisconnect();
+#else
+ USBDDR = (1<<USB_CFG_DMINUS_BIT)|(1<<USB_CFG_DPLUS_BIT);
+#endif
+
+ /* 250 ms disconnect */
+ wdt_reset();
+ _delay_ms(250);
+
+#ifdef USB_CFG_PULLUP_IOPORT
+ usbDeviceConnect();
+#else
+ USBDDR = 0; /* remove USB reset condition */
+#endif
+}
+
+
+
void handle_cmd(uint8_t cmd)
{
switch(cmd) {
@@ -52,19 +270,43 @@ int main(void)
cpu_init();
led_init();
-// usbio_init();
+ odDebugInit();
+ usbInit();
+ vusbio_init();
sei();
for(;;) {
- /* int16_t BytesReceived = usbio_bytes_received(); */
- /* while(BytesReceived > 0) { */
- /* int ReceivedByte = fgetc(stdin); */
- /* if(ReceivedByte != EOF) { */
- /* handle_cmd(ReceivedByte); */
- /* } */
- /* BytesReceived--; */
- /* } */
-
-// usbio_task();
+ }
+
+ intr3Status = 0;
+ sendEmptyFrame = 0;
+
+ sei();
+ for(;;) { /* main event loop */
+ wdt_reset();
+ usbPoll();
+
+ /* int16_t BytesReceived = vusbio_bytes_received(); */
+ /* while(BytesReceived > 0) { */
+ /* int ReceivedByte = fgetc(stdin); */
+ /* if(ReceivedByte != EOF) { */
+ /* handle_cmd(ReceivedByte); */
+ /* } */
+ /* BytesReceived--; */
+ /* } */
+
+// vusbio_task();
+
+ /* We need to report rx and tx carrier after open attempt */
+ if(intr3Status != 0 && usbInterruptIsReady3()){
+ static uchar serialStateNotification[10] = {0xa1, 0x20, 0, 0, 0, 0, 2, 0, 3, 0};
+
+ if(intr3Status == 2){
+ usbSetInterrupt3(serialStateNotification, 8);
+ }else{
+ usbSetInterrupt3(serialStateNotification+8, 2);
+ }
+ intr3Status--;
+ }
}
}