From d03fe64dcf80633c7ec78f122682e78fb59fe2d8 Mon Sep 17 00:00:00 2001 From: Michael Sparmann Date: Tue, 20 Oct 2009 06:37:07 +0000 Subject: iPod Nano 2G USB support based on the S3C6400X datasheet. Disabled by default for now. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23285 a1c6a512-1295-4272-9138-f99709370657 --- firmware/SOURCES | 2 +- firmware/export/config-ipodnano2g.h | 12 +- firmware/export/usb-s3c6400x.h | 341 ++++++++++++++++++++++++ firmware/target/arm/s5l8700/usb-s5l8700.c | 56 ---- firmware/target/arm/usb-s3c6400x.c | 429 ++++++++++++++++++++++++++++++ firmware/usb.c | 4 + firmware/usbstack/usb_storage.c | 6 + 7 files changed, 790 insertions(+), 60 deletions(-) create mode 100644 firmware/export/usb-s3c6400x.h delete mode 100644 firmware/target/arm/s5l8700/usb-s5l8700.c create mode 100644 firmware/target/arm/usb-s3c6400x.c diff --git a/firmware/SOURCES b/firmware/SOURCES index b91d49b7f7..a3c47a6ddb 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -1326,6 +1326,7 @@ target/arm/s5l8700/udacodec-meizu.c #ifdef IPOD_NANO2G #ifndef SIMULATOR drivers/audio/wm8975.c +target/arm/usb-s3c6400x.c target/arm/ipod/button-clickwheel.c target/arm/s5l8700/kernel-s5l8700.c target/arm/s5l8700/wmcodec-s5l8700.c @@ -1333,7 +1334,6 @@ target/arm/s5l8700/pcm-s5l8700.c target/arm/s5l8700/adc-s5l8700.c target/arm/s5l8700/debug-s5l8700.c target/arm/s5l8700/dma-s5l8700.c -target/arm/s5l8700/usb-s5l8700.c target/arm/s5l8700/ipodnano2g/backlight-nano2g.c target/arm/s5l8700/ipodnano2g/lcd-nano2g.c target/arm/s5l8700/ipodnano2g/powermgmt-nano2g.c diff --git a/firmware/export/config-ipodnano2g.h b/firmware/export/config-ipodnano2g.h index 25e9eff3f0..0946610eac 100644 --- a/firmware/export/config-ipodnano2g.h +++ b/firmware/export/config-ipodnano2g.h @@ -161,9 +161,6 @@ /* USB On-the-go */ //#define CONFIG_USBOTG USBOTG_M5636 -/* We reboot into the OF to handle USB */ -#define USB_HANDLED_BY_OF - /* Define this if you can read an absolute wheel position */ #define HAVE_WHEEL_POSITION @@ -201,3 +198,12 @@ #define MIN_BRIGHTNESS_SETTING 1 #define MAX_BRIGHTNESS_SETTING 0x2e #define DEFAULT_BRIGHTNESS_SETTING 0x20 + +/* USB defines */ +#define HAVE_USBSTACK +#define USB_ENABLE_STORAGE +#define USB_VENDOR_ID 0x05AC +#define USB_PRODUCT_ID 0x1260 +#define USB_NUM_ENDPOINTS 5 +/* #define USE_ROCKBOX_USB - needs testing */ +#define USB_DEVBSS_ATTR __attribute__((aligned(16))) diff --git a/firmware/export/usb-s3c6400x.h b/firmware/export/usb-s3c6400x.h new file mode 100644 index 0000000000..22b0769681 --- /dev/null +++ b/firmware/export/usb-s3c6400x.h @@ -0,0 +1,341 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 Michael Sparmann + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef USB_S3C6400X_H +#define USB_S3C6400X_H + + +#define REG32_PTR_T volatile uint32_t * + + +/*** OTG PHY CONTROL REGISTERS ***/ +#define OPHYPWR *(REG32_PTR_T)(PHYBASE + 0x000) +#define OPHYCLK *(REG32_PTR_T)(PHYBASE + 0x004) +#define ORSTCON *(REG32_PTR_T)(PHYBASE + 0x008) + +/*** OTG LINK CORE REGISTERS ***/ +/* Core Global Registers */ +#define GOTGCTL *(REG32_PTR_T)(OTGBASE + 0x000) +#define GOTGINT *(REG32_PTR_T)(OTGBASE + 0x004) +#define GAHBCFG *(REG32_PTR_T)(OTGBASE + 0x008) +#define GUSBCFG *(REG32_PTR_T)(OTGBASE + 0x00C) +#define GRSTCTL *(REG32_PTR_T)(OTGBASE + 0x010) +#define GINTSTS *(REG32_PTR_T)(OTGBASE + 0x014) +#define GINTMSK *(REG32_PTR_T)(OTGBASE + 0x018) +#define GRXSTSR *(REG32_PTR_T)(OTGBASE + 0x01C) +#define GRXSTSP *(REG32_PTR_T)(OTGBASE + 0x020) +#define GRXFSIZ *(REG32_PTR_T)(OTGBASE + 0x024) +#define GNPTXFSIZ *(REG32_PTR_T)(OTGBASE + 0x028) +#define GNPTXSTS *(REG32_PTR_T)(OTGBASE + 0x02C) +#define HPTXFSIZ *(REG32_PTR_T)(OTGBASE + 0x100) +#define DPTXFSIZ(x) *(REG32_PTR_T)(OTGBASE + 0x100 + 4 * x) +#define DPTXFSIZ1 *(REG32_PTR_T)(OTGBASE + 0x104) +#define DPTXFSIZ2 *(REG32_PTR_T)(OTGBASE + 0x108) +#define DPTXFSIZ3 *(REG32_PTR_T)(OTGBASE + 0x10C) +#define DPTXFSIZ4 *(REG32_PTR_T)(OTGBASE + 0x110) +#define DPTXFSIZ5 *(REG32_PTR_T)(OTGBASE + 0x114) +#define DPTXFSIZ6 *(REG32_PTR_T)(OTGBASE + 0x118) +#define DPTXFSIZ7 *(REG32_PTR_T)(OTGBASE + 0x11C) +#define DPTXFSIZ8 *(REG32_PTR_T)(OTGBASE + 0x120) +#define DPTXFSIZ9 *(REG32_PTR_T)(OTGBASE + 0x124) +#define DPTXFSIZ10 *(REG32_PTR_T)(OTGBASE + 0x128) +#define DPTXFSIZ11 *(REG32_PTR_T)(OTGBASE + 0x12C) +#define DPTXFSIZ12 *(REG32_PTR_T)(OTGBASE + 0x130) +#define DPTXFSIZ13 *(REG32_PTR_T)(OTGBASE + 0x134) +#define DPTXFSIZ14 *(REG32_PTR_T)(OTGBASE + 0x138) +#define DPTXFSIZ15 *(REG32_PTR_T)(OTGBASE + 0x13C) + +/*** HOST MODE REGISTERS ***/ +/* Host Global Registers */ +#define HCFG *(REG32_PTR_T)(OTGBASE + 0x400) +#define HFIR *(REG32_PTR_T)(OTGBASE + 0x404) +#define HFNUM *(REG32_PTR_T)(OTGBASE + 0x408) +#define HPTXSTS *(REG32_PTR_T)(OTGBASE + 0x410) +#define HAINT *(REG32_PTR_T)(OTGBASE + 0x414) +#define HAINTMSK *(REG32_PTR_T)(OTGBASE + 0x418) + +/* Host Port Control and Status Registers */ +#define HPRT *(REG32_PTR_T)(OTGBASE + 0x440) + +/* Host Channel-Specific Registers */ +#define HCCHAR(x) *(REG32_PTR_T)(OTGBASE + 0x500 + 0x20 * x) +#define HCSPLT(x) *(REG32_PTR_T)(OTGBASE + 0x504 + 0x20 * x) +#define HCINT(x) *(REG32_PTR_T)(OTGBASE + 0x508 + 0x20 * x) +#define HCINTMSK(x) *(REG32_PTR_T)(OTGBASE + 0x50C + 0x20 * x) +#define HCTSIZ(x) *(REG32_PTR_T)(OTGBASE + 0x510 + 0x20 * x) +#define HCDMA(x) *(REG32_PTR_T)(OTGBASE + 0x514 + 0x20 * x) +#define HCCHAR0 *(REG32_PTR_T)(OTGBASE + 0x500) +#define HCSPLT0 *(REG32_PTR_T)(OTGBASE + 0x504) +#define HCINT0 *(REG32_PTR_T)(OTGBASE + 0x508) +#define HCINTMSK0 *(REG32_PTR_T)(OTGBASE + 0x50C) +#define HCTSIZ0 *(REG32_PTR_T)(OTGBASE + 0x510) +#define HCDMA0 *(REG32_PTR_T)(OTGBASE + 0x514) +#define HCCHAR1 *(REG32_PTR_T)(OTGBASE + 0x520) +#define HCSPLT1 *(REG32_PTR_T)(OTGBASE + 0x524) +#define HCINT1 *(REG32_PTR_T)(OTGBASE + 0x528) +#define HCINTMSK1 *(REG32_PTR_T)(OTGBASE + 0x52C) +#define HCTSIZ1 *(REG32_PTR_T)(OTGBASE + 0x530) +#define HCDMA1 *(REG32_PTR_T)(OTGBASE + 0x534) +#define HCCHAR2 *(REG32_PTR_T)(OTGBASE + 0x540) +#define HCSPLT2 *(REG32_PTR_T)(OTGBASE + 0x544) +#define HCINT2 *(REG32_PTR_T)(OTGBASE + 0x548) +#define HCINTMSK2 *(REG32_PTR_T)(OTGBASE + 0x54C) +#define HCTSIZ2 *(REG32_PTR_T)(OTGBASE + 0x550) +#define HCDMA2 *(REG32_PTR_T)(OTGBASE + 0x554) +#define HCCHAR3 *(REG32_PTR_T)(OTGBASE + 0x560) +#define HCSPLT3 *(REG32_PTR_T)(OTGBASE + 0x564) +#define HCINT3 *(REG32_PTR_T)(OTGBASE + 0x568) +#define HCINTMSK3 *(REG32_PTR_T)(OTGBASE + 0x56C) +#define HCTSIZ3 *(REG32_PTR_T)(OTGBASE + 0x570) +#define HCDMA3 *(REG32_PTR_T)(OTGBASE + 0x574) +#define HCCHAR4 *(REG32_PTR_T)(OTGBASE + 0x580) +#define HCSPLT4 *(REG32_PTR_T)(OTGBASE + 0x584) +#define HCINT4 *(REG32_PTR_T)(OTGBASE + 0x588) +#define HCINTMSK4 *(REG32_PTR_T)(OTGBASE + 0x58C) +#define HCTSIZ4 *(REG32_PTR_T)(OTGBASE + 0x590) +#define HCDMA4 *(REG32_PTR_T)(OTGBASE + 0x594) +#define HCCHAR5 *(REG32_PTR_T)(OTGBASE + 0x5A0) +#define HCSPLT5 *(REG32_PTR_T)(OTGBASE + 0x5A4) +#define HCINT5 *(REG32_PTR_T)(OTGBASE + 0x5A8) +#define HCINTMSK5 *(REG32_PTR_T)(OTGBASE + 0x5AC) +#define HCTSIZ5 *(REG32_PTR_T)(OTGBASE + 0x5B0) +#define HCDMA5 *(REG32_PTR_T)(OTGBASE + 0x5B4) +#define HCCHAR6 *(REG32_PTR_T)(OTGBASE + 0x5C0) +#define HCSPLT6 *(REG32_PTR_T)(OTGBASE + 0x5C4) +#define HCINT6 *(REG32_PTR_T)(OTGBASE + 0x5C8) +#define HCINTMSK6 *(REG32_PTR_T)(OTGBASE + 0x5CC) +#define HCTSIZ6 *(REG32_PTR_T)(OTGBASE + 0x5D0) +#define HCDMA6 *(REG32_PTR_T)(OTGBASE + 0x5D4) +#define HCCHAR7 *(REG32_PTR_T)(OTGBASE + 0x5E0) +#define HCSPLT7 *(REG32_PTR_T)(OTGBASE + 0x5E4) +#define HCINT7 *(REG32_PTR_T)(OTGBASE + 0x5E8) +#define HCINTMSK7 *(REG32_PTR_T)(OTGBASE + 0x5EC) +#define HCTSIZ7 *(REG32_PTR_T)(OTGBASE + 0x5F0) +#define HCDMA7 *(REG32_PTR_T)(OTGBASE + 0x5F4) +#define HCCHAR8 *(REG32_PTR_T)(OTGBASE + 0x600) +#define HCSPLT8 *(REG32_PTR_T)(OTGBASE + 0x604) +#define HCINT8 *(REG32_PTR_T)(OTGBASE + 0x608) +#define HCINTMSK8 *(REG32_PTR_T)(OTGBASE + 0x60C) +#define HCTSIZ8 *(REG32_PTR_T)(OTGBASE + 0x610) +#define HCDMA8 *(REG32_PTR_T)(OTGBASE + 0x614) +#define HCCHAR9 *(REG32_PTR_T)(OTGBASE + 0x620) +#define HCSPLT9 *(REG32_PTR_T)(OTGBASE + 0x624) +#define HCINT9 *(REG32_PTR_T)(OTGBASE + 0x628) +#define HCINTMSK9 *(REG32_PTR_T)(OTGBASE + 0x62C) +#define HCTSIZ9 *(REG32_PTR_T)(OTGBASE + 0x630) +#define HCDMA9 *(REG32_PTR_T)(OTGBASE + 0x634) +#define HCCHAR10 *(REG32_PTR_T)(OTGBASE + 0x640) +#define HCSPLT10 *(REG32_PTR_T)(OTGBASE + 0x644) +#define HCINT10 *(REG32_PTR_T)(OTGBASE + 0x648) +#define HCINTMSK10 *(REG32_PTR_T)(OTGBASE + 0x64C) +#define HCTSIZ10 *(REG32_PTR_T)(OTGBASE + 0x650) +#define HCDMA10 *(REG32_PTR_T)(OTGBASE + 0x654) +#define HCCHAR11 *(REG32_PTR_T)(OTGBASE + 0x660) +#define HCSPLT11 *(REG32_PTR_T)(OTGBASE + 0x664) +#define HCINT11 *(REG32_PTR_T)(OTGBASE + 0x668) +#define HCINTMSK11 *(REG32_PTR_T)(OTGBASE + 0x66C) +#define HCTSIZ11 *(REG32_PTR_T)(OTGBASE + 0x670) +#define HCDMA11 *(REG32_PTR_T)(OTGBASE + 0x674) +#define HCCHAR12 *(REG32_PTR_T)(OTGBASE + 0x680) +#define HCSPLT12 *(REG32_PTR_T)(OTGBASE + 0x684) +#define HCINT12 *(REG32_PTR_T)(OTGBASE + 0x688) +#define HCINTMSK12 *(REG32_PTR_T)(OTGBASE + 0x68C) +#define HCTSIZ12 *(REG32_PTR_T)(OTGBASE + 0x690) +#define HCDMA12 *(REG32_PTR_T)(OTGBASE + 0x694) +#define HCCHAR13 *(REG32_PTR_T)(OTGBASE + 0x6A0) +#define HCSPLT13 *(REG32_PTR_T)(OTGBASE + 0x6A4) +#define HCINT13 *(REG32_PTR_T)(OTGBASE + 0x6A8) +#define HCINTMSK13 *(REG32_PTR_T)(OTGBASE + 0x6AC) +#define HCTSIZ13 *(REG32_PTR_T)(OTGBASE + 0x6B0) +#define HCDMA13 *(REG32_PTR_T)(OTGBASE + 0x6B4) +#define HCCHAR14 *(REG32_PTR_T)(OTGBASE + 0x6C0) +#define HCSPLT14 *(REG32_PTR_T)(OTGBASE + 0x6C4) +#define HCINT14 *(REG32_PTR_T)(OTGBASE + 0x6C8) +#define HCINTMSK14 *(REG32_PTR_T)(OTGBASE + 0x6CC) +#define HCTSIZ14 *(REG32_PTR_T)(OTGBASE + 0x6D0) +#define HCDMA14 *(REG32_PTR_T)(OTGBASE + 0x6D4) +#define HCCHAR15 *(REG32_PTR_T)(OTGBASE + 0x6E0) +#define HCSPLT15 *(REG32_PTR_T)(OTGBASE + 0x6E4) +#define HCINT15 *(REG32_PTR_T)(OTGBASE + 0x6E8) +#define HCINTMSK15 *(REG32_PTR_T)(OTGBASE + 0x6EC) +#define HCTSIZ15 *(REG32_PTR_T)(OTGBASE + 0x6F0) +#define HCDMA15 *(REG32_PTR_T)(OTGBASE + 0x6F4) + +/*** DEVICE MODE REGISTERS ***/ +/* Device Global Registers */ +#define DCFG *(REG32_PTR_T)(OTGBASE + 0x800) +#define DCTL *(REG32_PTR_T)(OTGBASE + 0x804) +#define DSTS *(REG32_PTR_T)(OTGBASE + 0x808) +#define DIEPMSK *(REG32_PTR_T)(OTGBASE + 0x810) +#define DOEPMSK *(REG32_PTR_T)(OTGBASE + 0x814) +#define DAINT *(REG32_PTR_T)(OTGBASE + 0x818) +#define DAINTMSK *(REG32_PTR_T)(OTGBASE + 0x81C) +#define DTKNQR1 *(REG32_PTR_T)(OTGBASE + 0x820) +#define DTKNQR2 *(REG32_PTR_T)(OTGBASE + 0x824) +#define DVBUSDIS *(REG32_PTR_T)(OTGBASE + 0x828) +#define DVBUSPULSE *(REG32_PTR_T)(OTGBASE + 0x82C) +#define DTKNQR3 *(REG32_PTR_T)(OTGBASE + 0x830) +#define DTKNQR4 *(REG32_PTR_T)(OTGBASE + 0x834) + +/* Device Logical IN Endpoint-Specific Registers */ +#define DIEPCTL(x) *(REG32_PTR_T)(OTGBASE + 0x900 + 0x20 * x) +#define DIEPINT(x) *(REG32_PTR_T)(OTGBASE + 0x908 + 0x20 * x) +#define DIEPTSIZ(x) *(REG32_PTR_T)(OTGBASE + 0x910 + 0x20 * x) +#define DIEPDMA(x) *(REG32_PTR_T)(OTGBASE + 0x914 + 0x20 * x) +#define DIEPCTL0 *(REG32_PTR_T)(OTGBASE + 0x900) +#define DIEPINT0 *(REG32_PTR_T)(OTGBASE + 0x908) +#define DIEPTSIZ0 *(REG32_PTR_T)(OTGBASE + 0x910) +#define DIEPDMA0 *(REG32_PTR_T)(OTGBASE + 0x914) +#define DIEPCTL1 *(REG32_PTR_T)(OTGBASE + 0x920) +#define DIEPINT1 *(REG32_PTR_T)(OTGBASE + 0x928) +#define DIEPTSIZ1 *(REG32_PTR_T)(OTGBASE + 0x930) +#define DIEPDMA1 *(REG32_PTR_T)(OTGBASE + 0x934) +#define DIEPCTL2 *(REG32_PTR_T)(OTGBASE + 0x940) +#define DIEPINT2 *(REG32_PTR_T)(OTGBASE + 0x948) +#define DIEPTSIZ2 *(REG32_PTR_T)(OTGBASE + 0x950) +#define DIEPDMA2 *(REG32_PTR_T)(OTGBASE + 0x954) +#define DIEPCTL3 *(REG32_PTR_T)(OTGBASE + 0x960) +#define DIEPINT3 *(REG32_PTR_T)(OTGBASE + 0x968) +#define DIEPTSIZ3 *(REG32_PTR_T)(OTGBASE + 0x970) +#define DIEPDMA3 *(REG32_PTR_T)(OTGBASE + 0x974) +#define DIEPCTL4 *(REG32_PTR_T)(OTGBASE + 0x980) +#define DIEPINT4 *(REG32_PTR_T)(OTGBASE + 0x988) +#define DIEPTSIZ4 *(REG32_PTR_T)(OTGBASE + 0x990) +#define DIEPDMA4 *(REG32_PTR_T)(OTGBASE + 0x994) +#define DIEPCTL5 *(REG32_PTR_T)(OTGBASE + 0x9A0) +#define DIEPINT5 *(REG32_PTR_T)(OTGBASE + 0x9A8) +#define DIEPTSIZ5 *(REG32_PTR_T)(OTGBASE + 0x9B0) +#define DIEPDMA5 *(REG32_PTR_T)(OTGBASE + 0x9B4) +#define DIEPCTL6 *(REG32_PTR_T)(OTGBASE + 0x9C0) +#define DIEPINT6 *(REG32_PTR_T)(OTGBASE + 0x9C8) +#define DIEPTSIZ6 *(REG32_PTR_T)(OTGBASE + 0x9D0) +#define DIEPDMA6 *(REG32_PTR_T)(OTGBASE + 0x9D4) +#define DIEPCTL7 *(REG32_PTR_T)(OTGBASE + 0x9E0) +#define DIEPINT7 *(REG32_PTR_T)(OTGBASE + 0x9E8) +#define DIEPTSIZ7 *(REG32_PTR_T)(OTGBASE + 0x9F0) +#define DIEPDMA7 *(REG32_PTR_T)(OTGBASE + 0x9F4) +#define DIEPCTL8 *(REG32_PTR_T)(OTGBASE + 0xA00) +#define DIEPINT8 *(REG32_PTR_T)(OTGBASE + 0xA08) +#define DIEPTSIZ8 *(REG32_PTR_T)(OTGBASE + 0xA10) +#define DIEPDMA8 *(REG32_PTR_T)(OTGBASE + 0xA14) +#define DIEPCTL9 *(REG32_PTR_T)(OTGBASE + 0xA20) +#define DIEPINT9 *(REG32_PTR_T)(OTGBASE + 0xA28) +#define DIEPTSIZ9 *(REG32_PTR_T)(OTGBASE + 0xA30) +#define DIEPDMA9 *(REG32_PTR_T)(OTGBASE + 0xA34) +#define DIEPCTL10 *(REG32_PTR_T)(OTGBASE + 0xA40) +#define DIEPINT10 *(REG32_PTR_T)(OTGBASE + 0xA48) +#define DIEPTSIZ10 *(REG32_PTR_T)(OTGBASE + 0xA50) +#define DIEPDMA10 *(REG32_PTR_T)(OTGBASE + 0xA54) +#define DIEPCTL11 *(REG32_PTR_T)(OTGBASE + 0xA60) +#define DIEPINT11 *(REG32_PTR_T)(OTGBASE + 0xA68) +#define DIEPTSIZ11 *(REG32_PTR_T)(OTGBASE + 0xA70) +#define DIEPDMA11 *(REG32_PTR_T)(OTGBASE + 0xA74) +#define DIEPCTL12 *(REG32_PTR_T)(OTGBASE + 0xA80) +#define DIEPINT12 *(REG32_PTR_T)(OTGBASE + 0xA88) +#define DIEPTSIZ12 *(REG32_PTR_T)(OTGBASE + 0xA90) +#define DIEPDMA12 *(REG32_PTR_T)(OTGBASE + 0xA94) +#define DIEPCTL13 *(REG32_PTR_T)(OTGBASE + 0xAA0) +#define DIEPINT13 *(REG32_PTR_T)(OTGBASE + 0xAA8) +#define DIEPTSIZ13 *(REG32_PTR_T)(OTGBASE + 0xAB0) +#define DIEPDMA13 *(REG32_PTR_T)(OTGBASE + 0xAB4) +#define DIEPCTL14 *(REG32_PTR_T)(OTGBASE + 0xAC0) +#define DIEPINT14 *(REG32_PTR_T)(OTGBASE + 0xAC8) +#define DIEPTSIZ14 *(REG32_PTR_T)(OTGBASE + 0xAD0) +#define DIEPDMA14 *(REG32_PTR_T)(OTGBASE + 0xAD4) +#define DIEPCTL15 *(REG32_PTR_T)(OTGBASE + 0xAE0) +#define DIEPINT15 *(REG32_PTR_T)(OTGBASE + 0xAE8) +#define DIEPTSIZ15 *(REG32_PTR_T)(OTGBASE + 0xAF0) +#define DIEPDMA15 *(REG32_PTR_T)(OTGBASE + 0xAF4) + +/* Device Logical OUT Endpoint-Specific Registers */ +#define DOEPCTL(x) *(REG32_PTR_T)(OTGBASE + 0xB00 + 0x20 * x) +#define DOEPINT(x) *(REG32_PTR_T)(OTGBASE + 0xB08 + 0x20 * x) +#define DOEPTSIZ(x) *(REG32_PTR_T)(OTGBASE + 0xB10 + 0x20 * x) +#define DOEPDMA(x) *(REG32_PTR_T)(OTGBASE + 0xB14 + 0x20 * x) +#define DOEPCTL0 *(REG32_PTR_T)(OTGBASE + 0xB00) +#define DOEPINT0 *(REG32_PTR_T)(OTGBASE + 0xB08) +#define DOEPTSIZ0 *(REG32_PTR_T)(OTGBASE + 0xB10) +#define DOEPDMA0 *(REG32_PTR_T)(OTGBASE + 0xB14) +#define DOEPCTL1 *(REG32_PTR_T)(OTGBASE + 0xB20) +#define DOEPINT1 *(REG32_PTR_T)(OTGBASE + 0xB28) +#define DOEPTSIZ1 *(REG32_PTR_T)(OTGBASE + 0xB30) +#define DOEPDMA1 *(REG32_PTR_T)(OTGBASE + 0xB34) +#define DOEPCTL2 *(REG32_PTR_T)(OTGBASE + 0xB40) +#define DOEPINT2 *(REG32_PTR_T)(OTGBASE + 0xB48) +#define DOEPTSIZ2 *(REG32_PTR_T)(OTGBASE + 0xB50) +#define DOEPDMA2 *(REG32_PTR_T)(OTGBASE + 0xB54) +#define DOEPCTL3 *(REG32_PTR_T)(OTGBASE + 0xB60) +#define DOEPINT3 *(REG32_PTR_T)(OTGBASE + 0xB68) +#define DOEPTSIZ3 *(REG32_PTR_T)(OTGBASE + 0xB70) +#define DOEPDMA3 *(REG32_PTR_T)(OTGBASE + 0xB74) +#define DOEPCTL4 *(REG32_PTR_T)(OTGBASE + 0xB80) +#define DOEPINT4 *(REG32_PTR_T)(OTGBASE + 0xB88) +#define DOEPTSIZ4 *(REG32_PTR_T)(OTGBASE + 0xB90) +#define DOEPDMA4 *(REG32_PTR_T)(OTGBASE + 0xB94) +#define DOEPCTL5 *(REG32_PTR_T)(OTGBASE + 0xBA0) +#define DOEPINT5 *(REG32_PTR_T)(OTGBASE + 0xBA8) +#define DOEPTSIZ5 *(REG32_PTR_T)(OTGBASE + 0xBB0) +#define DOEPDMA5 *(REG32_PTR_T)(OTGBASE + 0xBB4) +#define DOEPCTL6 *(REG32_PTR_T)(OTGBASE + 0xBC0) +#define DOEPINT6 *(REG32_PTR_T)(OTGBASE + 0xBC8) +#define DOEPTSIZ6 *(REG32_PTR_T)(OTGBASE + 0xBD0) +#define DOEPDMA6 *(REG32_PTR_T)(OTGBASE + 0xBD4) +#define DOEPCTL7 *(REG32_PTR_T)(OTGBASE + 0xBE0) +#define DOEPINT7 *(REG32_PTR_T)(OTGBASE + 0xBE8) +#define DOEPTSIZ7 *(REG32_PTR_T)(OTGBASE + 0xBF0) +#define DOEPDMA7 *(REG32_PTR_T)(OTGBASE + 0xBF4) +#define DOEPCTL8 *(REG32_PTR_T)(OTGBASE + 0xC00) +#define DOEPINT8 *(REG32_PTR_T)(OTGBASE + 0xC08) +#define DOEPTSIZ8 *(REG32_PTR_T)(OTGBASE + 0xC10) +#define DOEPDMA8 *(REG32_PTR_T)(OTGBASE + 0xC14) +#define DOEPCTL9 *(REG32_PTR_T)(OTGBASE + 0xC20) +#define DOEPINT9 *(REG32_PTR_T)(OTGBASE + 0xC28) +#define DOEPTSIZ9 *(REG32_PTR_T)(OTGBASE + 0xC30) +#define DOEPDMA9 *(REG32_PTR_T)(OTGBASE + 0xC34) +#define DOEPCTL10 *(REG32_PTR_T)(OTGBASE + 0xC40) +#define DOEPINT10 *(REG32_PTR_T)(OTGBASE + 0xC48) +#define DOEPTSIZ10 *(REG32_PTR_T)(OTGBASE + 0xC50) +#define DOEPDMA10 *(REG32_PTR_T)(OTGBASE + 0xC54) +#define DOEPCTL11 *(REG32_PTR_T)(OTGBASE + 0xC60) +#define DOEPINT11 *(REG32_PTR_T)(OTGBASE + 0xC68) +#define DOEPTSIZ11 *(REG32_PTR_T)(OTGBASE + 0xC70) +#define DOEPDMA11 *(REG32_PTR_T)(OTGBASE + 0xC74) +#define DOEPCTL12 *(REG32_PTR_T)(OTGBASE + 0xC80) +#define DOEPINT12 *(REG32_PTR_T)(OTGBASE + 0xC88) +#define DOEPTSIZ12 *(REG32_PTR_T)(OTGBASE + 0xC90) +#define DOEPDMA12 *(REG32_PTR_T)(OTGBASE + 0xC94) +#define DOEPCTL13 *(REG32_PTR_T)(OTGBASE + 0xCA0) +#define DOEPINT13 *(REG32_PTR_T)(OTGBASE + 0xCA8) +#define DOEPTSIZ13 *(REG32_PTR_T)(OTGBASE + 0xCB0) +#define DOEPDMA13 *(REG32_PTR_T)(OTGBASE + 0xCB4) +#define DOEPCTL14 *(REG32_PTR_T)(OTGBASE + 0xCC0) +#define DOEPINT14 *(REG32_PTR_T)(OTGBASE + 0xCC8) +#define DOEPTSIZ14 *(REG32_PTR_T)(OTGBASE + 0xCD0) +#define DOEPDMA14 *(REG32_PTR_T)(OTGBASE + 0xCD4) +#define DOEPCTL15 *(REG32_PTR_T)(OTGBASE + 0xCE0) +#define DOEPINT15 *(REG32_PTR_T)(OTGBASE + 0xCE8) +#define DOEPTSIZ15 *(REG32_PTR_T)(OTGBASE + 0xCF0) +#define DOEPDMA15 *(REG32_PTR_T)(OTGBASE + 0xCF4) + +/* Power and Clock Gating Register */ +#define PCGCCTL *(REG32_PTR_T)(OTGBASE + 0xE00) + + +#endif /* USB_S3C6400X_H */ diff --git a/firmware/target/arm/s5l8700/usb-s5l8700.c b/firmware/target/arm/s5l8700/usb-s5l8700.c deleted file mode 100644 index c0bf7a951b..0000000000 --- a/firmware/target/arm/s5l8700/usb-s5l8700.c +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id: usb-fw-pp502x.c 21932 2009-07-17 22:07:06Z roolku $ - * - * Copyright (C) 2009 by ????? - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include "config.h" -#include "usb.h" -#include "cpu.h" -#include "system.h" -#include "string.h" - -void usb_init_device(void) -{ -} - -void usb_enable(bool on) -{ - /* This device specific code will eventually give way to proper USB - handling, which should be the same for all S5L870x targets. */ - if (on) - { -#ifdef IPOD_ARCH - /* For iPod, we can only do one thing with USB mode atm - reboot - into the flash-based disk-mode. This does not return. */ - - memcpy((void *)0x0002bf00, "diskmodehotstuff\1\0\0\0", 20); - - system_reboot(); /* Reboot */ -#endif - } -} - -int usb_detect(void) -{ -#if defined(IPOD_NANO2G) - if ((PDAT14 & 0x8) == 0x0) - return USB_INSERTED; -#endif - - return USB_EXTRACTED; -} diff --git a/firmware/target/arm/usb-s3c6400x.c b/firmware/target/arm/usb-s3c6400x.c new file mode 100644 index 0000000000..3034cf8029 --- /dev/null +++ b/firmware/target/arm/usb-s3c6400x.c @@ -0,0 +1,429 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Michael Sparmann + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" +#include "usb.h" + +#define OTGBASE 0x38800000 +#define PHYBASE 0x3C400000 +#include "usb-s3c6400x.h" + +#include "cpu.h" +#include "system.h" +#include "kernel.h" +#include "panic.h" + +#ifdef HAVE_USBSTACK +#include "usb_ch9.h" +#include "usb_core.h" +#include +#include "sprintf.h" +#include "power.h" + +struct ep_type +{ + bool active; + bool busy; + bool done; + int rc; + int size; + struct wakeup complete; +} ; + +static struct ep_type endpoints[5]; +static struct usb_ctrlrequest ctrlreq USB_DEVBSS_ATTR; + +int usb_drv_port_speed(void) +{ + return (DSTS & 2) == 0 ? 1 : 0; +} + +void reset_endpoints(int reinit) +{ + unsigned int i; + for (i = 0; i < sizeof(endpoints)/sizeof(struct ep_type); i++) + { + if (reinit) endpoints[i].active = false; + endpoints[i].busy = false; + endpoints[i].rc = -1; + endpoints[i].done = true; + wakeup_signal(&endpoints[i].complete); + } + DIEPCTL0 = 0x8800; /* EP0 IN ACTIVE NEXT=1 */ + DOEPCTL0 = 0x8000; /* EP0 OUT ACTIVE */ + DOEPTSIZ0 = 0x20080040; /* EP0 OUT Transfer Size: + 64 Bytes, 1 Packet, 1 Setup Packet */ + DOEPDMA0 = (uint32_t)&ctrlreq; + DOEPCTL0 |= 0x84000000; /* EP0 OUT ENABLE CLEARNAK */ + if (reinit) + { + /* The size is getting set to zero, because we don't know + whether we are Full Speed or High Speed at this stage */ + /* EP1 IN INACTIVE DATA0 SIZE=0 NEXT=3 */ + DIEPCTL1 = 0x10001800; + /* EP2 OUT INACTIVE DATA0 SIZE=0 */ + DOEPCTL2 = 0x10000000; + /* EP3 IN INACTIVE DATA0 SIZE=0 NEXT=0 */ + DIEPCTL3 = 0x10000000; + /* EP4 OUT INACTIVE DATA0 SIZE=0 */ + DOEPCTL4 = 0x10000000; + } + else + { + /* INACTIVE DATA0 */ + DIEPCTL1 = (DIEPCTL1 & ~0x00008000) | 0x10000000; + DOEPCTL2 = (DOEPCTL2 & ~0x00008000) | 0x10000000; + DIEPCTL3 = (DIEPCTL3 & ~0x00008000) | 0x10000000; + DOEPCTL4 = (DOEPCTL4 & ~0x00008000) | 0x10000000; + } + DAINTMSK = 0xFFFFFFFF; /* Enable interrupts on all EPs */ +} + +int usb_drv_request_endpoint(int type, int dir) +{ + size_t ep; + int ret = -1; + + if (dir == USB_DIR_IN) ep = 1; + else ep = 2; + + while (ep < 5) + { + if (!endpoints[ep].active) + { + endpoints[ep].active = true; + ret = ep | dir; + uint32_t newbits = (type << 18) | 0x10000000; + if (dir) DIEPCTL(ep) = (DIEPCTL(ep) & ~0x000C0000) | newbits; + else DOEPCTL(ep) = (DOEPCTL(ep) & ~0x000C0000) | newbits; + break; + } + ep += 2; + } + + return ret; +} + +void usb_drv_release_endpoint(int ep) +{ + ep = ep & 0x7f; + + if (ep < 1 || ep > USB_NUM_ENDPOINTS) return; + + endpoints[ep].active = false; +} + +static void usb_reset(void) +{ + volatile int i; + + DCTL = 0x802; /* Soft Disconnect */ + + OPHYPWR = 0; /* PHY: Power up */ + ORSTCON = 1; /* PHY: Assert Software Reset */ + for (i = 0; i < 50; i++); + ORSTCON = 0; /* PHY: Deassert Software Reset */ + OPHYCLK = 0; /* PHY: 48MHz clock */ + + GRSTCTL = 1; /* OTG: Assert Software Reset */ + while (GRSTCTL & 1); /* Wait for OTG to ack reset */ + while (!(GRSTCTL & 0x80000000)); /* Wait for OTG AHB master idle */ + + GAHBCFG = 0x27; /* OTG AHB config: Unmask ints, burst length 4, DMA on */ + GUSBCFG = 0x1408; /* OTG: 16bit PHY and some reserved bits */ + + DCFG = 4; /* Address 0 */ + DCTL = 0x800; /* Soft Reconnect */ + DIEPMSK = 0x0D; /* IN EP interrupt mask */ + DOEPMSK = 0x0D; /* IN EP interrupt mask */ + GINTMSK = 0xC3000; /* Interrupt mask: IN event, OUT event, bus reset */ + + reset_endpoints(1); +} + +/* IRQ handler */ +void INT_USB_FUNC(void) +{ + int i; + if (GINTSTS & 0x1000) /* bus reset */ + { + DCFG = 4; /* Address 0 */ + reset_endpoints(1); + usb_core_bus_reset(); + } + + if (GINTSTS & 0x2000) /* enumeration done, we now know the speed */ + { + /* Set up the maximum packet sizes accordingly */ + uint32_t maxpacket = usb_drv_port_speed() ? 512 : 64; + DIEPCTL1 = (DIEPCTL1 & ~0x000003FF) | maxpacket; + DOEPCTL2 = (DOEPCTL2 & ~0x000003FF) | maxpacket; + DIEPCTL3 = (DIEPCTL3 & ~0x000003FF) | maxpacket; + DOEPCTL4 = (DOEPCTL4 & ~0x000003FF) | maxpacket; + } + + if (GINTSTS & 0x40000) /* IN EP event */ + for (i = 0; i < 5; i ++) + if (i != 2 && i != 4 && DIEPINT(i)) + { + if (DIEPINT(i) & 1) /* Transfer completed */ + { + invalidate_dcache(); + int bytes = endpoints[i].size - (DIEPTSIZ(i) & 0x3FFFF); + if (endpoints[i].busy) + { + endpoints[i].busy = false; + endpoints[i].rc = 0; + endpoints[i].done = true; + usb_core_transfer_complete(i, USB_DIR_IN, 0, bytes); + wakeup_signal(&endpoints[i].complete); + } + } + if (DIEPINT(i) & 4) /* AHB error */ + panicf("USB: AHB error on IN EP%d", i); + if (DIEPINT(i) & 8) /* Timeout */ + { + if (endpoints[i].busy) + { + endpoints[i].busy = false; + endpoints[i].rc = 1; + endpoints[i].done = true; + wakeup_signal(&endpoints[i].complete); + } + } + DIEPINT(i) = DIEPINT(i); + } + + if (GINTSTS & 0x80000) /* OUT EP event */ + for (i = 0; i < 5; i += 2) + if (DOEPINT(i)) + { + if (DOEPINT(i) & 1) /* Transfer completed */ + { + invalidate_dcache(); + int bytes = endpoints[i].size - (DOEPTSIZ(i) & 0x3FFFF); + if (endpoints[i].busy) + { + endpoints[i].busy = false; + endpoints[i].rc = 0; + endpoints[i].done = true; + usb_core_transfer_complete(i, USB_DIR_OUT, 0, bytes); + wakeup_signal(&endpoints[i].complete); + } + } + if (DOEPINT(i) & 4) /* AHB error */ + panicf("USB: AHB error on OUT EP%d", i); + if (DOEPINT(i) & 8) /* SETUP phase done */ + { + invalidate_dcache(); + if (i == 0) + { + if (ctrlreq.bRequest == 5) + { + /* Already set the new address here, + before passing the packet to the core. + See below (usb_drv_set_address) for details. */ + DCFG = (DCFG & ~0x7F0) | (ctrlreq.wValue << 4); + } + usb_core_control_request(&ctrlreq); + } + else panicf("USB: SETUP done on OUT EP%d!?", i); + } + /* Make sure EP0 OUT is set up to accept the next request */ + if (!i) + { + DOEPTSIZ0 = 0x20080040; + DOEPDMA0 = (uint32_t)&ctrlreq; + DOEPCTL0 |= 0x84000000; + } + DOEPINT(i) = DOEPINT(i); + } + + GINTSTS = GINTSTS; +} + +void usb_drv_set_address(int address) +{ + (void)address; + /* Ignored intentionally, because the controller requires us to set the + new address before sending the response for some reason. So we'll + already set it when the control request arrives, before passing that + into the USB core, which will then call this dummy function. */ +} + +void ep_send(int ep, void *ptr, int length) +{ + endpoints[ep].busy = true; + endpoints[ep].size = length; + DIEPCTL(ep) |= 0x8000; /* EPx OUT ACTIVE */ + int blocksize = usb_drv_port_speed() ? 512 : 64; + int packets = (length + blocksize - 1) / blocksize; + if (!length) DIEPTSIZ(ep) = 1 << 19; /* one empty packet */ + else DIEPTSIZ(ep) = length | (packets << 19); + DIEPDMA(ep) = (uint32_t)ptr; + clean_dcache(); + DIEPCTL(ep) |= 0x84000000; /* EPx OUT ENABLE CLEARNAK */ +} + +void ep_recv(int ep, void *ptr, int length) +{ + endpoints[ep].busy = true; + endpoints[ep].size = length; + DOEPCTL(ep) &= ~0x20000; /* EPx UNSTALL */ + DOEPCTL(ep) |= 0x8000; /* EPx OUT ACTIVE */ + int blocksize = usb_drv_port_speed() ? 512 : 64; + int packets = (length + blocksize - 1) / blocksize; + if (!length) DIEPTSIZ(ep) = 1 << 19; /* one empty packet */ + else DOEPTSIZ(ep) = length | (packets << 19); + DOEPDMA(ep) = (uint32_t)ptr; + clean_dcache(); + DOEPCTL(ep) |= 0x84000000; /* EPx OUT ENABLE CLEARNAK */ +} + +int usb_drv_send(int endpoint, void *ptr, int length) +{ + endpoint &= 0x7f; + endpoints[endpoint].done = false; + ep_send(endpoint, ptr, length); + while (!endpoints[endpoint].done && endpoints[endpoint].busy) + wakeup_wait(&endpoints[endpoint].complete, TIMEOUT_BLOCK); + return endpoints[endpoint].rc; +} + +int usb_drv_send_nonblocking(int endpoint, void *ptr, int length) +{ + ep_send(endpoint & 0x7f, ptr, length); + return 0; +} + +int usb_drv_recv(int endpoint, void* ptr, int length) +{ + ep_recv(endpoint & 0x7f, ptr, length); + return 0; +} + +void usb_drv_cancel_all_transfers(void) +{ + int flags = disable_irq_save(); + reset_endpoints(0); + restore_irq(flags); +} + +void usb_drv_set_test_mode(int mode) +{ + (void)mode; +} + +bool usb_drv_stalled(int endpoint, bool in) +{ + if (in) return DIEPCTL(endpoint) & 0x00200000 ? true : false; + else return DOEPCTL(endpoint) & 0x00200000 ? true : false; +} + +void usb_drv_stall(int endpoint, bool stall, bool in) +{ + if (in) + { + if (stall) DIEPCTL(endpoint) |= 0x00200000; + else DIEPCTL(endpoint) &= ~0x00200000; + } + else + { + if (stall) DOEPCTL(endpoint) |= 0x00200000; + else DOEPCTL(endpoint) &= ~0x00200000; + } +} + +void usb_drv_init(void) +{ + /* Enable USB clock */ + PWRCON &= ~0x4000; + PWRCONEXT &= ~0x800; + PCGCCTL = 0; + + /* unmask irq */ + INTMSK |= INTMSK_USB_OTG; + + /* reset the beast */ + usb_reset(); +} + +void usb_drv_exit(void) +{ + DCTL = 0x802; /* Soft Disconnect */ + + OPHYPWR = 0xF; /* PHY: Power down */ + + PCGCCTL = 1; /* Mask clocks */ + PWRCON |= 0x4000; + PWRCONEXT |= 0x800; +} + +void usb_init_device(void) +{ + unsigned int i; + for (i = 0; i < sizeof(endpoints)/sizeof(struct ep_type); i++) + wakeup_init(&endpoints[i].complete); + usb_drv_exit(); +} + +void usb_enable(bool on) +{ + if (on) usb_core_init(); + else usb_core_exit(); +} + +void usb_attach(void) +{ + usb_enable(true); +} + +int usb_detect(void) +{ + if (charger_inserted()) + return USB_INSERTED; + return USB_EXTRACTED; +} + +#else +void usb_init_device(void) +{ + /* simply switch USB off for now */ + DCTL = 0x802; /* Soft Disconnect */ + + OPHYPWR = 0xF; /* PHY: Power down */ + + PCGCCTL = 1; /* Mask clocks */ + PWRCON |= 0x4000; + PWRCONEXT |= 0x800; +} + +void usb_enable(bool on) +{ + (void)on; +} + +/* Always return false for now */ +int usb_detect(void) +{ + return USB_EXTRACTED; +} +#endif diff --git a/firmware/usb.c b/firmware/usb.c index ea07a8447d..bac1258d50 100644 --- a/firmware/usb.c +++ b/firmware/usb.c @@ -109,6 +109,10 @@ static void try_reboot(void) #endif /* CONFIG_CPU */ #endif /* IPOD_ARCH */ +#ifdef IPOD_NANO2G + memcpy((void *)0x0002bf00, "diskmodehotstuff\1\0\0\0", 20); +#endif + system_reboot(); /* Reboot */ } #endif /* USB_FIRWIRE_HANDLING || (HAVE_USBSTACK && !USE_ROCKBOX_USB) */ diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c index d16277a5f1..88a669b64a 100644 --- a/firmware/usbstack/usb_storage.c +++ b/firmware/usbstack/usb_storage.c @@ -44,7 +44,9 @@ #define RAMDISK_SIZE 2048 #endif +#ifndef SECTOR_SIZE #define SECTOR_SIZE 512 +#endif /* the ARC driver currently supports up to 64k USB transfers. This is * enough for efficient mass storage support, as commonly host OSes @@ -454,7 +456,11 @@ void usb_storage_init_connection(void) unsigned char * audio_buffer; audio_buffer = audio_get_buffer(false,&bufsize); +#ifdef UNCACHED_ADDR cbw_buffer = (void *)UNCACHED_ADDR((unsigned int)(audio_buffer+31) & 0xffffffe0); +#else + cbw_buffer = (void *)((unsigned int)(audio_buffer+31) & 0xffffffe0); +#endif tb.transfer_buffer = cbw_buffer + 1024; cpucache_invalidate(); #ifdef USB_USE_RAMDISK -- cgit v1.2.3