forked from len0rd/rockbox
Add a working serial driver to usb stack. At the moment it simply echos back what it gets. You can test it on linux by
0) change relevant defines in usb_core.c 1) modprobe usbserial vendor=0x0781 product=0x7421 debug=1 2) picocom /dev/ttyUSB0 3) look at your logf screen if you build with logf support and enabled LOGF_ENABLE define in usb_serial.c I also modified usb_core so that storage and serial both can make use the the 'usb_core'-thread. More will come :) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15850 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
bf2a33485f
commit
94be71eab5
4 changed files with 143 additions and 11 deletions
|
|
@ -229,6 +229,7 @@ drivers/audio/mas35xx.c
|
||||||
#ifdef HAVE_USBSTACK
|
#ifdef HAVE_USBSTACK
|
||||||
usbstack/usb_core.c
|
usbstack/usb_core.c
|
||||||
usbstack/usb_storage.c
|
usbstack/usb_storage.c
|
||||||
|
usbstack/usb_serial.c
|
||||||
usbstack/usb_benchmark.c
|
usbstack/usb_benchmark.c
|
||||||
#ifdef CPU_PP502x
|
#ifdef CPU_PP502x
|
||||||
target/arm/usb-drv-pp502x.c
|
target/arm/usb-drv-pp502x.c
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
* \/ \/ \/ \/ \/
|
* \/ \/ \/ \/ \/
|
||||||
* $Id: $
|
* $Id: $
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007 by Björn Stenberg
|
* Copyright (C) 2007 by Bj<EFBFBD>rn Stenberg
|
||||||
*
|
*
|
||||||
* All files in this archive are subject to the GNU General Public License.
|
* All files in this archive are subject to the GNU General Public License.
|
||||||
* See the file COPYING in the source tree root for full license agreement.
|
* See the file COPYING in the source tree root for full license agreement.
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
#include "logf.h"
|
#include "logf.h"
|
||||||
|
|
||||||
//#define USB_STORAGE
|
//#define USB_STORAGE
|
||||||
|
//#define USB_SERIAL
|
||||||
//#define USB_BENCHMARK
|
//#define USB_BENCHMARK
|
||||||
#define USB_CHARGING_ONLY
|
#define USB_CHARGING_ONLY
|
||||||
|
|
||||||
|
|
@ -33,6 +34,10 @@
|
||||||
|
|
||||||
#if defined(USB_STORAGE)
|
#if defined(USB_STORAGE)
|
||||||
#include "usb_storage.h"
|
#include "usb_storage.h"
|
||||||
|
#define USB_THREAD
|
||||||
|
#elif defined(USB_SERIAL)
|
||||||
|
#define USB_THREAD
|
||||||
|
#include "usb_serial.h"
|
||||||
#elif defined(USB_BENCHMARK)
|
#elif defined(USB_BENCHMARK)
|
||||||
#include "usb_benchmark.h"
|
#include "usb_benchmark.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -79,7 +84,7 @@ static const struct {
|
||||||
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
|
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
|
||||||
.bMaxPower = 250, /* 500mA in 2mA units */
|
.bMaxPower = 250, /* 500mA in 2mA units */
|
||||||
},
|
},
|
||||||
|
|
||||||
#ifdef USB_CHARGING_ONLY
|
#ifdef USB_CHARGING_ONLY
|
||||||
/* dummy interface for charging-only */
|
/* dummy interface for charging-only */
|
||||||
{
|
{
|
||||||
|
|
@ -163,7 +168,7 @@ static const struct {
|
||||||
.bDescriptorType = USB_DT_ENDPOINT,
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
.bEndpointAddress = EP_TX | USB_DIR_IN,
|
.bEndpointAddress = EP_TX | USB_DIR_IN,
|
||||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||||
.wMaxPacketSize = 512,
|
.wMaxPacketSize = 64,
|
||||||
.bInterval = 0
|
.bInterval = 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -171,7 +176,7 @@ static const struct {
|
||||||
.bDescriptorType = USB_DT_ENDPOINT,
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
.bEndpointAddress = EP_RX | USB_DIR_OUT,
|
.bEndpointAddress = EP_RX | USB_DIR_OUT,
|
||||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||||
.wMaxPacketSize = 512,
|
.wMaxPacketSize = 64,
|
||||||
.bInterval = 0
|
.bInterval = 0
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -296,7 +301,7 @@ static bool data_connection = false;
|
||||||
static struct event_queue usbcore_queue;
|
static struct event_queue usbcore_queue;
|
||||||
static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
|
static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
|
||||||
|
|
||||||
#ifdef USB_STORAGE
|
#ifdef USB_THREAD
|
||||||
static const char usbcore_thread_name[] = "usb_core";
|
static const char usbcore_thread_name[] = "usb_core";
|
||||||
static struct thread_entry* usbcore_thread;
|
static struct thread_entry* usbcore_thread;
|
||||||
static long usbcore_stack[DEFAULT_STACK_SIZE];
|
static long usbcore_stack[DEFAULT_STACK_SIZE];
|
||||||
|
|
@ -314,6 +319,13 @@ void usb_core_init(void)
|
||||||
usb_drv_init();
|
usb_drv_init();
|
||||||
#ifdef USB_STORAGE
|
#ifdef USB_STORAGE
|
||||||
usb_storage_init();
|
usb_storage_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USB_SERIAL
|
||||||
|
usb_serial_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USB_THREAD
|
||||||
usbcore_thread =
|
usbcore_thread =
|
||||||
create_thread(usb_core_thread, usbcore_stack, sizeof(usbcore_stack), 0,
|
create_thread(usb_core_thread, usbcore_stack, sizeof(usbcore_stack), 0,
|
||||||
usbcore_thread_name
|
usbcore_thread_name
|
||||||
|
|
@ -334,7 +346,7 @@ void usb_core_exit(void)
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
usb_drv_exit();
|
usb_drv_exit();
|
||||||
queue_delete(&usbcore_queue);
|
queue_delete(&usbcore_queue);
|
||||||
#ifdef USB_STORAGE
|
#ifdef USB_THREAD
|
||||||
remove_thread(usbcore_thread);
|
remove_thread(usbcore_thread);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -348,15 +360,22 @@ bool usb_core_data_connection(void)
|
||||||
return data_connection;
|
return data_connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USB_STORAGE
|
#ifdef USB_THREAD
|
||||||
void usb_core_thread(void)
|
void usb_core_thread(void)
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
struct queue_event ev;
|
struct queue_event ev;
|
||||||
|
|
||||||
queue_wait(&usbcore_queue, &ev);
|
queue_wait(&usbcore_queue, &ev);
|
||||||
|
|
||||||
|
#ifdef USB_STORAGE
|
||||||
usb_storage_transfer_complete(ev.id);
|
usb_storage_transfer_complete(ev.id);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USB_SERIAL
|
||||||
|
usb_serial_transfer_complete(ev.id);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -380,6 +399,10 @@ void usb_core_control_request(struct usb_ctrlrequest* req)
|
||||||
#ifdef USB_STORAGE
|
#ifdef USB_STORAGE
|
||||||
usb_storage_control_request(req);
|
usb_storage_control_request(req);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USB_SERIAL
|
||||||
|
usb_serial_control_request(req);
|
||||||
|
#endif
|
||||||
ack_control(req);
|
ack_control(req);
|
||||||
if (req->wValue)
|
if (req->wValue)
|
||||||
usb_state = CONFIGURED;
|
usb_state = CONFIGURED;
|
||||||
|
|
@ -399,7 +422,7 @@ void usb_core_control_request(struct usb_ctrlrequest* req)
|
||||||
ack_control(req);
|
ack_control(req);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case USB_REQ_SET_INTERFACE:
|
case USB_REQ_SET_INTERFACE:
|
||||||
logf("usb_core: SET_INTERFACE");
|
logf("usb_core: SET_INTERFACE");
|
||||||
ack_control(req);
|
ack_control(req);
|
||||||
|
|
@ -517,6 +540,11 @@ void usb_core_control_request(struct usb_ctrlrequest* req)
|
||||||
/* does usb_storage know this request? */
|
/* does usb_storage know this request? */
|
||||||
if (!usb_storage_control_request(req))
|
if (!usb_storage_control_request(req))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USB_SERIAL
|
||||||
|
/* does usb_serial know this request? */
|
||||||
|
if (!usb_serial_control_request(req))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/* nope. flag error */
|
/* nope. flag error */
|
||||||
logf("usb bad req %d", req->bRequest);
|
logf("usb bad req %d", req->bRequest);
|
||||||
|
|
@ -551,11 +579,11 @@ void usb_core_transfer_complete(int endpoint, bool in)
|
||||||
case EP_TX:
|
case EP_TX:
|
||||||
#if defined(USB_BENCHMARK)
|
#if defined(USB_BENCHMARK)
|
||||||
usb_benchmark_transfer_complete(endpoint, in);
|
usb_benchmark_transfer_complete(endpoint, in);
|
||||||
#elif defined(USB_STORAGE)
|
#elif defined(USB_STORAGE) || defined(USB_SERIAL)
|
||||||
queue_post(&usbcore_queue, endpoint, 0);
|
queue_post(&usbcore_queue, endpoint, 0);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
74
firmware/usbstack/usb_serial.c
Normal file
74
firmware/usbstack/usb_serial.c
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id: $
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 by Christian Gmeiner
|
||||||
|
*
|
||||||
|
* All files in this archive are subject to the GNU General Public License.
|
||||||
|
* See the file COPYING in the source tree root for full license agreement.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
#include "system.h"
|
||||||
|
#include "usb_core.h"
|
||||||
|
#include "usb_drv.h"
|
||||||
|
|
||||||
|
//#define LOGF_ENABLE
|
||||||
|
#include "logf.h"
|
||||||
|
|
||||||
|
static unsigned char _transfer_buffer[16];
|
||||||
|
static unsigned char* transfer_buffer;
|
||||||
|
|
||||||
|
/* called by usb_code_init() */
|
||||||
|
void usb_serial_init(void)
|
||||||
|
{
|
||||||
|
logf("serial: init");
|
||||||
|
transfer_buffer = (void*)UNCACHED_ADDR(&_transfer_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* called by usb_core_transfer_complete() */
|
||||||
|
void usb_serial_transfer_complete(int endpoint)
|
||||||
|
{
|
||||||
|
switch (endpoint) {
|
||||||
|
case EP_RX:
|
||||||
|
logf("serial: %s", transfer_buffer);
|
||||||
|
|
||||||
|
/* re-prime endpoint */
|
||||||
|
usb_drv_recv(EP_RX, transfer_buffer, sizeof _transfer_buffer);
|
||||||
|
|
||||||
|
/* echo back :) */
|
||||||
|
usb_drv_send(EP_TX, transfer_buffer, sizeof transfer_buffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EP_TX:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* called by usb_core_control_request() */
|
||||||
|
bool usb_serial_control_request(struct usb_ctrlrequest* req)
|
||||||
|
{
|
||||||
|
/* note: interrupt context */
|
||||||
|
|
||||||
|
bool handled = false;
|
||||||
|
switch (req->bRequest) {
|
||||||
|
case USB_REQ_SET_CONFIGURATION:
|
||||||
|
logf("serial: set config");
|
||||||
|
/* prime rx endpoint */
|
||||||
|
usb_drv_recv(EP_RX, transfer_buffer, sizeof _transfer_buffer);
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
logf("serial: unhandeld req %d", req->bRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
29
firmware/usbstack/usb_serial.h
Normal file
29
firmware/usbstack/usb_serial.h
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id: $
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 by Christian Gmeiner
|
||||||
|
*
|
||||||
|
* All files in this archive are subject to the GNU General Public License.
|
||||||
|
* See the file COPYING in the source tree root for full license agreement.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef USB_SERIAL_H
|
||||||
|
#define USB_SERIAL_H
|
||||||
|
|
||||||
|
#include "usb_ch9.h"
|
||||||
|
|
||||||
|
void usb_serial_init(void);
|
||||||
|
void usb_serial_transfer_complete(int endpoint);
|
||||||
|
bool usb_serial_control_request(struct usb_ctrlrequest* req);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue