Compare commits
No commits in common. "master" and "progmem" have entirely different histories.
4
.ditz-config
Normal file
4
.ditz-config
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
--- !ditz.rubyforge.org,2008-03-06/config
|
||||||
|
name: David
|
||||||
|
email: david@optixx.org
|
||||||
|
issue_dir: bugs
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
@ -34,10 +34,5 @@ tmtags
|
|||||||
bsnes
|
bsnes
|
||||||
web
|
web
|
||||||
ucon64.exe
|
ucon64.exe
|
||||||
project
|
|
||||||
huffman-decode
|
|
||||||
huffman-encode
|
|
||||||
unpack
|
|
||||||
pack
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
```
|
|
||||||
________ .__ __ ________ ____ ________
|
________ .__ __ ________ ____ ________
|
||||||
\_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
\_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
/ / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
/ / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
@ -6,6 +5,4 @@
|
|||||||
\_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
\_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
\__> \/ \/ \/ \/ \/
|
\__> \/ \/ \/ \/ \/
|
||||||
|
|
||||||
```
|
www.optixx.org
|
||||||
[Go to the Documentation](../../wiki)
|
|
||||||
|
|
||||||
@ -33,10 +33,6 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "usbdrv/usbdrv.c"
|
#include "usbdrv/usbdrv.c"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* USBasp requests, taken from the original USBasp sourcecode
|
* USBasp requests, taken from the original USBasp sourcecode
|
||||||
*/
|
*/
|
||||||
@ -78,12 +74,8 @@
|
|||||||
(LED_DIR ^= (1 << LED_PIN)));}
|
(LED_DIR ^= (1 << LED_PIN)));}
|
||||||
|
|
||||||
|
|
||||||
#define AVR_BTLDR_EN_PORT PORTC
|
|
||||||
#define AVR_BTLDR_EN_DIR DDRC
|
|
||||||
#define AVR_BTLDR_EN_PIN PC1
|
|
||||||
#define AVR_BTLDR_EN_IN PINC
|
|
||||||
|
|
||||||
#undef AVR_BTLDR_SWITCH
|
|
||||||
/*
|
/*
|
||||||
* some predefined signatures, taken from the original USBasp sourcecode
|
* some predefined signatures, taken from the original USBasp sourcecode
|
||||||
*/
|
*/
|
||||||
@ -457,28 +449,6 @@ int __attribute__ ((noreturn, OS_main)) main(void)
|
|||||||
uint16_t delay = 0;
|
uint16_t delay = 0;
|
||||||
timeout = TIMEOUT;
|
timeout = TIMEOUT;
|
||||||
|
|
||||||
DDRC &= ~(1 << AVR_BTLDR_EN_PIN);
|
|
||||||
PORTC &= ~(1 << AVR_BTLDR_EN_PIN);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if watchdog reset, disable watchdog and jump to app
|
|
||||||
*/
|
|
||||||
if (reset & _BV(WDRF)) {
|
|
||||||
uart_puts("Found watchdog reset\n\r");
|
|
||||||
MCUSR = 0;
|
|
||||||
wdt_disable();
|
|
||||||
uart_puts("Jump to 0x0000\n\r");
|
|
||||||
jump_to_app();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if AVR_BTLDR_SWITCH_ENABLE
|
|
||||||
if ((AVR_BTLDR_EN_IN & ( 1 << AVR_BTLDR_EN_PIN)) == 0){
|
|
||||||
banner();
|
|
||||||
uart_puts("Bootloader flashing is disabled\n\r");
|
|
||||||
MCUSR = 0;
|
|
||||||
leave_bootloader();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if power-on reset, quit bootloader via watchdog reset
|
* if power-on reset, quit bootloader via watchdog reset
|
||||||
@ -489,6 +459,17 @@ int __attribute__ ((noreturn, OS_main)) main(void)
|
|||||||
MCUSR = 0;
|
MCUSR = 0;
|
||||||
leave_bootloader();
|
leave_bootloader();
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* if watchdog reset, disable watchdog and jump to app
|
||||||
|
*/
|
||||||
|
else if (reset & _BV(WDRF)) {
|
||||||
|
uart_puts("Found watchdog reset\n\r");
|
||||||
|
MCUSR = 0;
|
||||||
|
wdt_disable();
|
||||||
|
uart_puts("Jump to 0x0000\n\r");
|
||||||
|
jump_to_app();
|
||||||
|
}
|
||||||
|
|
||||||
banner();
|
banner();
|
||||||
uart_puts("Enter programming mode\n\r");
|
uart_puts("Enter programming mode\n\r");
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -20,4 +20,3 @@
|
|||||||
|
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
#define DEBUG_USB 2
|
#define DEBUG_USB 2
|
||||||
#define AVR_BTLDR_SWITCH_ENABLE 1
|
|
||||||
|
|||||||
@ -231,99 +231,3 @@ Scroll down to the bottom to see the most recent changes.
|
|||||||
- Added 20 MHz module contributed by Jeroen Benschop.
|
- Added 20 MHz module contributed by Jeroen Benschop.
|
||||||
|
|
||||||
* Release 2008-05-13
|
* Release 2008-05-13
|
||||||
|
|
||||||
- Fixed bug in libs-host/hiddata.c function usbhidGetReport(): length
|
|
||||||
was not incremented, pointer to length was incremented instead.
|
|
||||||
- Added code to command line tool(s) which claims an interface. This code
|
|
||||||
is disabled by default, but may be necessary on newer Linux kernels.
|
|
||||||
- Added usbconfig.h option "USB_CFG_CHECK_DATA_TOGGLING".
|
|
||||||
- New header "usbportability.h" prepares ports to other development
|
|
||||||
environments.
|
|
||||||
- Long transfers (above 254 bytes) did not work when usbFunctionRead() was
|
|
||||||
used to supply the data. Fixed this bug. [Thanks to Alexander Neumann!]
|
|
||||||
- In hiddata.c (example code for sending/receiving data over HID), use
|
|
||||||
USB_RECIP_DEVICE instead of USB_RECIP_INTERFACE for control transfers so
|
|
||||||
that we need not claim the interface.
|
|
||||||
- in usbPoll() loop 20 times polling for RESET state instead of 10 times.
|
|
||||||
This accounts for the higher clock rates we now support.
|
|
||||||
- Added a module for 12.8 MHz RC oscillator with PLL in receiver loop.
|
|
||||||
- Added hook to SOF code so that oscillator can be tuned to USB frame clock.
|
|
||||||
- Added timeout to waitForJ loop. Helps preventing unexpected hangs.
|
|
||||||
- Added example code for oscillator tuning to libs-device (thanks to
|
|
||||||
Henrik Haftmann for the idea to this routine).
|
|
||||||
- Implemented option USB_CFG_SUPPRESS_INTR_CODE.
|
|
||||||
|
|
||||||
* Release 2008-10-22
|
|
||||||
|
|
||||||
- Fixed libs-device/osctune.h: OSCCAL is memory address on ATMega88 and
|
|
||||||
similar, not offset of 0x20 needs to be added.
|
|
||||||
- Allow distribution under GPLv3 for those who have to link against other
|
|
||||||
code distributed under GPLv3.
|
|
||||||
|
|
||||||
* Release 2008-11-26
|
|
||||||
|
|
||||||
- Removed libusb-win32 dependency for hid-data example in Makefile.windows.
|
|
||||||
It was never required and confused many people.
|
|
||||||
- Added extern uchar usbRxToken to usbdrv.h.
|
|
||||||
- Integrated a module with CRC checks at 18 MHz by Lukas Schrittwieser.
|
|
||||||
|
|
||||||
* Release 2009-03-23
|
|
||||||
|
|
||||||
- Hid-mouse example used settings from hid-data example, fixed that.
|
|
||||||
- Renamed project to V-USB due to a trademark issue with Atmel(r).
|
|
||||||
- Changed CommercialLicense.txt and USBID-License.txt to make the
|
|
||||||
background of USB ID registration clearer.
|
|
||||||
|
|
||||||
* Release 2009-04-15
|
|
||||||
|
|
||||||
- Changed CommercialLicense.txt to reflect the new range of PIDs from
|
|
||||||
Jason Kotzin.
|
|
||||||
- Removed USBID-License.txt in favor of USB-IDs-for-free.txt and
|
|
||||||
USB-ID-FAQ.txt
|
|
||||||
- Fixed a bug in the 12.8 MHz module: End Of Packet decection was made in
|
|
||||||
the center between bit 0 and 1 of each byte. This is where the data lines
|
|
||||||
are expected to change and the sampled data may therefore be nonsense.
|
|
||||||
We therefore check EOP ONLY if bits 0 AND 1 have both been read as 0 on D-.
|
|
||||||
- Fixed a bitstuffing problem in the 16 MHz module: If bit 6 was stuffed,
|
|
||||||
the unstuffing code in the receiver routine was 1 cycle too long. If
|
|
||||||
multiple bytes had the unstuffing in bit 6, the error summed up until the
|
|
||||||
receiver was out of sync.
|
|
||||||
- Included option for faster CRC routine.
|
|
||||||
Thanks to Slawomir Fras (BoskiDialer) for this code!
|
|
||||||
- Updated bits in Configuration Descriptor's bmAttributes according to
|
|
||||||
USB 1.1 (in particular bit 7, it is a must-be-set bit now).
|
|
||||||
|
|
||||||
* Release 2009-08-22
|
|
||||||
|
|
||||||
- Moved first DBG1() after odDebugInit() in all examples.
|
|
||||||
- Use vector INT0_vect instead of SIG_INTERRUPT0 if defined. This makes
|
|
||||||
V-USB compatible with the new "p" suffix devices (e.g. ATMega328p).
|
|
||||||
- USB_CFG_CLOCK_KHZ setting is now required in usbconfig.h (no default any
|
|
||||||
more).
|
|
||||||
- New option USB_CFG_DRIVER_FLASH_PAGE allows boot loaders on devices with
|
|
||||||
more than 64 kB flash.
|
|
||||||
- Built-in configuration descriptor allows custom definition for second
|
|
||||||
endpoint now.
|
|
||||||
|
|
||||||
* Release 2010-07-15
|
|
||||||
|
|
||||||
- Fixed bug in usbDriverSetup() which prevented descriptor sizes above 255
|
|
||||||
bytes.
|
|
||||||
- Avoid a compiler warning for unused parameter in usbHandleResetHook() when
|
|
||||||
compiler option -Wextra is enabled.
|
|
||||||
- Fixed wrong hex value for some IDs in USB-IDs-for-free.txt.
|
|
||||||
- Keep a define for USBATTR_BUSPOWER, although the flag does not exist
|
|
||||||
in USB 1.1 any more. Set it to 0. This is for backward compatibility.
|
|
||||||
|
|
||||||
* Release 2012-01-09
|
|
||||||
|
|
||||||
- Define a separate (defined) type for usbMsgPtr so that projects using a
|
|
||||||
tiny memory model can define it to an 8 bit type in usbconfig.h. This
|
|
||||||
change also saves a couple of bytes when using a scalar 16 bit type.
|
|
||||||
- Inserted "const" keyword for all PROGMEM declarations because new GCC
|
|
||||||
requires it.
|
|
||||||
- Fixed problem with dependence of usbportability.h on usbconfig.h. This
|
|
||||||
problem occurred with IAR CC only.
|
|
||||||
- Prepared repository for github.com.
|
|
||||||
|
|
||||||
* Release 2012-12-06
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
V-USB Driver Software License Agreement
|
AVR-USB Driver Software License Agreement
|
||||||
Version 2012-07-09
|
Version 2008-04-15
|
||||||
|
|
||||||
THIS LICENSE AGREEMENT GRANTS YOU CERTAIN RIGHTS IN A SOFTWARE. YOU CAN
|
THIS LICENSE AGREEMENT GRANTS YOU CERTAIN RIGHTS IN A SOFTWARE. YOU CAN
|
||||||
ENTER INTO THIS AGREEMENT AND ACQUIRE THE RIGHTS OUTLINED BELOW BY PAYING
|
ENTER INTO THIS AGREEMENT AND ACQUIRE THE RIGHTS OUTLINED BELOW BY PAYING
|
||||||
@ -13,8 +13,8 @@ Grosse Schiffgasse 1A/7, 1020 Wien, AUSTRIA.
|
|||||||
|
|
||||||
1.2 "You" shall mean the Licensee.
|
1.2 "You" shall mean the Licensee.
|
||||||
|
|
||||||
1.3 "V-USB" shall mean all files included in the package distributed under
|
1.3 "AVR-USB" shall mean all files included in the package distributed under
|
||||||
the name "vusb" by OBJECTIVE DEVELOPMENT (http://www.obdev.at/vusb/)
|
the name "avrusb" by OBJECTIVE DEVELOPMENT (http://www.obdev.at/avrusb/)
|
||||||
unless otherwise noted. This includes the firmware-only USB device
|
unless otherwise noted. This includes the firmware-only USB device
|
||||||
implementation for Atmel AVR microcontrollers, some simple device examples
|
implementation for Atmel AVR microcontrollers, some simple device examples
|
||||||
and host side software examples and libraries.
|
and host side software examples and libraries.
|
||||||
@ -23,31 +23,21 @@ and host side software examples and libraries.
|
|||||||
2 LICENSE GRANTS
|
2 LICENSE GRANTS
|
||||||
|
|
||||||
2.1 Source Code. OBJECTIVE DEVELOPMENT shall furnish you with the source
|
2.1 Source Code. OBJECTIVE DEVELOPMENT shall furnish you with the source
|
||||||
code of V-USB.
|
code of AVR-USB.
|
||||||
|
|
||||||
2.2 Distribution and Use. OBJECTIVE DEVELOPMENT grants you the
|
2.2 Distribution and Use. OBJECTIVE DEVELOPMENT grants you the
|
||||||
non-exclusive right to use, copy and distribute V-USB with your hardware
|
non-exclusive right to use and distribute AVR-USB with your hardware
|
||||||
product(s), restricted by the limitations in section 3 below.
|
product(s), restricted by the limitations in section 3 below.
|
||||||
|
|
||||||
2.3 Modifications. OBJECTIVE DEVELOPMENT grants you the right to modify
|
2.3 Modifications. OBJECTIVE DEVELOPMENT grants you the right to modify
|
||||||
the source code and your copy of V-USB according to your needs.
|
your copy of AVR-USB according to your needs.
|
||||||
|
|
||||||
2.4 USB IDs. OBJECTIVE DEVELOPMENT furnishes you with one or two USB
|
2.4 USB IDs. OBJECTIVE DEVELOPMENT grants you the exclusive rights to use
|
||||||
Product ID(s), sent to you in e-mail. These Product IDs are reserved
|
USB Product ID(s) sent to you in e-mail after receiving your payment in
|
||||||
exclusively for you. OBJECTIVE DEVELOPMENT has obtained USB Product ID
|
conjunction with USB Vendor ID 5824. OBJECTIVE DEVELOPMENT has acquired an
|
||||||
ranges under the Vendor ID 5824 from Wouter van Ooijen (Van Ooijen
|
exclusive license for this pair of USB identifiers from Wouter van Ooijen
|
||||||
Technische Informatica, www.voti.nl) and under the Vendor ID 8352 from
|
(www.voti.nl), who has licensed the VID from the USB Implementers Forum,
|
||||||
Jason Kotzin (now flirc.tv, Inc.). Both owners of the Vendor IDs have
|
Inc. (www.usb.org).
|
||||||
obtained these IDs from the USB Implementers Forum, Inc. (www.usb.org).
|
|
||||||
OBJECTIVE DEVELOPMENT disclaims all liability which might arise from the
|
|
||||||
assignment of USB IDs.
|
|
||||||
|
|
||||||
2.5 USB Certification. Although not part of this agreement, we want to make
|
|
||||||
it clear that you cannot become USB certified when you use V-USB or a USB
|
|
||||||
Product ID assigned by OBJECTIVE DEVELOPMENT. AVR microcontrollers don't
|
|
||||||
meet the electrical specifications required by the USB specification and
|
|
||||||
the USB Implementers Forum certifies only members who bought a Vendor ID of
|
|
||||||
their own.
|
|
||||||
|
|
||||||
|
|
||||||
3 LICENSE RESTRICTIONS
|
3 LICENSE RESTRICTIONS
|
||||||
@ -56,21 +46,21 @@ their own.
|
|||||||
applicable. Which one is determined by the amount you pay to OBJECTIVE
|
applicable. Which one is determined by the amount you pay to OBJECTIVE
|
||||||
DEVELOPMENT, see section 4 ("Payment") below.
|
DEVELOPMENT, see section 4 ("Payment") below.
|
||||||
|
|
||||||
Hobby License: You may use V-USB according to section 2 above in no more
|
Hobby License: You may use AVR-USB according to section 2 above in no more
|
||||||
than 5 hardware units. These units must not be sold for profit.
|
than 5 hardware units. These units must not be sold for profit.
|
||||||
|
|
||||||
Entry Level License: You may use V-USB according to section 2 above in no
|
Entry Level License: You may use AVR-USB according to section 2 above in no
|
||||||
more than 150 hardware units.
|
more than 150 hardware units.
|
||||||
|
|
||||||
Professional License: You may use V-USB according to section 2 above in
|
Professional License: You may use AVR-USB according to section 2 above in
|
||||||
any number of hardware units, except for large scale production ("unlimited
|
any number of hardware units, except for large scale production ("unlimited
|
||||||
fair use"). Quantities below 10,000 units are not considered large scale
|
fair use"). Quantities below 10,000 units are not considered large scale
|
||||||
production. If your reach quantities which are obviously large scale
|
production. If your reach quantities which are obviously large scale
|
||||||
production, you must pay a license fee of 0.10 EUR per unit for all units
|
production, you must pay a license fee of 0.10 EUR per unit for all units
|
||||||
above 10,000.
|
above 10,000.
|
||||||
|
|
||||||
3.2 Rental. You may not rent, lease, or lend V-USB or otherwise encumber
|
3.2 Rental. You may not rent, lease, or lend AVR-USB or otherwise encumber
|
||||||
any copy of V-USB, or any of the rights granted herein.
|
any copy of AVR-USB, or any of the rights granted herein.
|
||||||
|
|
||||||
3.3 Transfer. You may not transfer your rights under this Agreement to
|
3.3 Transfer. You may not transfer your rights under this Agreement to
|
||||||
another party without OBJECTIVE DEVELOPMENT's prior written consent. If
|
another party without OBJECTIVE DEVELOPMENT's prior written consent. If
|
||||||
@ -88,7 +78,7 @@ non-exclusive.
|
|||||||
by third parties. In particular, you are not allowed to use the USB logo or
|
by third parties. In particular, you are not allowed to use the USB logo or
|
||||||
other trademarks owned by the USB Implementers Forum, Inc. without their
|
other trademarks owned by the USB Implementers Forum, Inc. without their
|
||||||
consent. Since such consent depends on USB certification, it should be
|
consent. Since such consent depends on USB certification, it should be
|
||||||
noted that V-USB will not pass certification because it does not
|
noted that AVR-USB will not pass certification because it does not
|
||||||
implement checksum verification and the microcontroller ports do not meet
|
implement checksum verification and the microcontroller ports do not meet
|
||||||
the electrical specifications.
|
the electrical specifications.
|
||||||
|
|
||||||
@ -98,15 +88,15 @@ the electrical specifications.
|
|||||||
The payment amount depends on the variation of this agreement (according to
|
The payment amount depends on the variation of this agreement (according to
|
||||||
section 3.1) into which you want to enter. Concrete prices are listed on
|
section 3.1) into which you want to enter. Concrete prices are listed on
|
||||||
OBJECTIVE DEVELOPMENT's web site, usually at
|
OBJECTIVE DEVELOPMENT's web site, usually at
|
||||||
http://www.obdev.at/vusb/license.html. You agree to pay the amount listed
|
http://www.obdev.at/avrusb/license.html. You agree to pay the amount listed
|
||||||
there to OBJECTIVE DEVELOPMENT or OBJECTIVE DEVELOPMENT's payment processor
|
there to OBJECTIVE DEVELOPMENT or OBJECTIVE DEVELOPMENT's payment processor
|
||||||
or reseller.
|
or reseller.
|
||||||
|
|
||||||
|
|
||||||
5 COPYRIGHT AND OWNERSHIP
|
5 COPYRIGHT AND OWNERSHIP
|
||||||
|
|
||||||
V-USB is protected by copyright laws and international copyright
|
AVR-USB is protected by copyright laws and international copyright
|
||||||
treaties, as well as other intellectual property laws and treaties. V-USB
|
treaties, as well as other intellectual property laws and treaties. AVR-USB
|
||||||
is licensed, not sold.
|
is licensed, not sold.
|
||||||
|
|
||||||
|
|
||||||
@ -122,12 +112,12 @@ and limitation of liability shall survive termination of this agreement.
|
|||||||
|
|
||||||
7 DISCLAIMER OF WARRANTY AND LIABILITY
|
7 DISCLAIMER OF WARRANTY AND LIABILITY
|
||||||
|
|
||||||
LIMITED WARRANTY. V-USB IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
LIMITED WARRANTY. AVR-USB IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
KIND. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, OBJECTIVE
|
KIND. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, OBJECTIVE
|
||||||
DEVELOPMENT AND ITS SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES, EITHER
|
DEVELOPMENT AND ITS SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES, EITHER
|
||||||
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
|
||||||
NON-INFRINGEMENT, WITH REGARD TO V-USB, AND THE PROVISION OF OR FAILURE
|
NON-INFRINGEMENT, WITH REGARD TO AVR-USB, AND THE PROVISION OF OR FAILURE
|
||||||
TO PROVIDE SUPPORT SERVICES. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL
|
TO PROVIDE SUPPORT SERVICES. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL
|
||||||
RIGHTS. YOU MAY HAVE OTHERS, WHICH VARY FROM STATE/JURISDICTION TO
|
RIGHTS. YOU MAY HAVE OTHERS, WHICH VARY FROM STATE/JURISDICTION TO
|
||||||
STATE/JURISDICTION.
|
STATE/JURISDICTION.
|
||||||
@ -137,11 +127,11 @@ IN NO EVENT SHALL OBJECTIVE DEVELOPMENT OR ITS SUPPLIERS BE LIABLE FOR ANY
|
|||||||
SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER
|
SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER
|
||||||
(INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
|
(INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
|
||||||
BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY
|
BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY
|
||||||
LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE V-USB OR THE
|
LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE AVR-USB OR THE
|
||||||
PROVISION OF OR FAILURE TO PROVIDE SUPPORT SERVICES, EVEN IF OBJECTIVE
|
PROVISION OF OR FAILURE TO PROVIDE SUPPORT SERVICES, EVEN IF OBJECTIVE
|
||||||
DEVELOPMENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY
|
DEVELOPMENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY
|
||||||
CASE, OBJECTIVE DEVELOPMENT'S ENTIRE LIABILITY UNDER ANY PROVISION OF THIS
|
CASE, OBJECTIVE DEVELOPMENT'S ENTIRE LIABILITY UNDER ANY PROVISION OF THIS
|
||||||
AGREEMENT SHALL BE LIMITED TO THE AMOUNT ACTUALLY PAID BY YOU FOR V-USB.
|
AGREEMENT SHALL BE LIMITED TO THE AMOUNT ACTUALLY PAID BY YOU FOR AVR-USB.
|
||||||
|
|
||||||
|
|
||||||
8 MISCELLANEOUS TERMS
|
8 MISCELLANEOUS TERMS
|
||||||
|
|||||||
@ -1,18 +1,16 @@
|
|||||||
OBJECTIVE DEVELOPMENT GmbH's V-USB driver software is distributed under the
|
OBJECTIVE DEVELOPMENT GmbH's AVR-USB driver software is distributed under the
|
||||||
terms and conditions of the GNU GPL version 2 or the GNU GPL version 3. It is
|
terms and conditions of the GNU GPL version 2, see the text below. In addition
|
||||||
your choice whether you apply the terms of version 2 or version 3. The full
|
to the requirements in the GPL, we STRONGLY ENCOURAGE you to do the following:
|
||||||
text of GPLv2 is included below. In addition to the requirements in the GPL,
|
|
||||||
we STRONGLY ENCOURAGE you to do the following:
|
|
||||||
|
|
||||||
(1) Publish your entire project on a web site and drop us a note with the URL.
|
(1) Publish your entire project on a web site and drop us a note with the URL.
|
||||||
Use the form at http://www.obdev.at/vusb/feedback.html for your submission.
|
Use the form at http://www.obdev.at/avrusb/feedback.html for your submission.
|
||||||
|
|
||||||
(2) Adhere to minimum publication standards. Please include AT LEAST:
|
(2) Adhere to minimum publication standards. Please include AT LEAST:
|
||||||
- a circuit diagram in PDF, PNG or GIF format
|
- a circuit diagram in PDF, PNG or GIF format
|
||||||
- full source code for the host software
|
- full source code for the host software
|
||||||
- a Readme.txt file in ASCII format which describes the purpose of the
|
- a Readme.txt file in ASCII format which describes the purpose of the
|
||||||
project and what can be found in which directories and which files
|
project and what can be found in which directories and which files
|
||||||
- a reference to http://www.obdev.at/vusb/
|
- a reference to http://www.obdev.at/avrusb/
|
||||||
|
|
||||||
(3) If you improve the driver firmware itself, please give us a free license
|
(3) If you improve the driver firmware itself, please give us a free license
|
||||||
to your modifications for our commercial license offerings.
|
to your modifications for our commercial license offerings.
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
This is the Readme file to Objective Development's firmware-only USB driver
|
This is the Readme file to Objective Development's firmware-only USB driver
|
||||||
for Atmel AVR microcontrollers. For more information please visit
|
for Atmel AVR microcontrollers. For more information please visit
|
||||||
http://www.obdev.at/vusb/
|
http://www.obdev.at/avrusb/
|
||||||
|
|
||||||
This directory contains the USB firmware only. Copy it as-is to your own
|
This directory contains the USB firmware only. Copy it as-is to your own
|
||||||
project and add all .c and .S files to your project (these files are marked
|
project and add all .c and .S files to your project (these files are marked
|
||||||
@ -33,26 +33,26 @@ The driver consists of the following files:
|
|||||||
defined to a value greater than 0. Link this module
|
defined to a value greater than 0. Link this module
|
||||||
to your code!
|
to your code!
|
||||||
oddebug.h .............. Interface definitions of the debug module.
|
oddebug.h .............. Interface definitions of the debug module.
|
||||||
usbportability.h ....... Header with compiler-dependent stuff.
|
iarcompat.h ............ Compatibility definitions for IAR C-compiler.
|
||||||
usbdrvasm.asm .......... Compatibility stub for IAR-C-compiler. Use this
|
usbdrvasm.asm .......... Compatibility stub for IAR-C-compiler. Use this
|
||||||
module instead of usbdrvasm.S when you assembler
|
module instead of usbdrvasm.S when you assembler
|
||||||
with IAR's tools.
|
with IAR's tools.
|
||||||
License.txt ............ Open Source license for this driver.
|
License.txt ............ Open Source license for this driver.
|
||||||
CommercialLicense.txt .. Optional commercial license for this driver.
|
CommercialLicense.txt .. Optional commercial license for this driver.
|
||||||
USB-ID-FAQ.txt ......... General infos about USB Product- and Vendor-IDs.
|
USBID-License.txt ...... Terms and conditions for using particular USB ID
|
||||||
USB-IDs-for-free.txt ... List and terms of use for free shared PIDs.
|
values for particular purposes.
|
||||||
|
|
||||||
(*) ... These files should be linked to your project.
|
(*) ... These files should be linked to your project.
|
||||||
|
|
||||||
|
|
||||||
CPU CORE CLOCK FREQUENCY
|
CPU CORE CLOCK FREQUENCY
|
||||||
========================
|
========================
|
||||||
We supply assembler modules for clock frequencies of 12 MHz, 12.8 MHz, 15 MHz,
|
We supply assembler modules for clock frequencies of 12 MHz, 15 MHz, 16 MHz and
|
||||||
16 MHz, 16.5 MHz 18 MHz and 20 MHz. Other clock rates are not supported. The
|
16.5 MHz. Other clock rates are not supported. The actual clock rate must be
|
||||||
actual clock rate must be configured in usbconfig.h.
|
configured in usbdrv.h unless you use the default 12 MHz.
|
||||||
|
|
||||||
12 MHz Clock
|
12 MHz Clock
|
||||||
This is the traditional clock rate of V-USB because it's the lowest clock
|
This is the traditional clock rate of AVR-USB because it's the lowest clock
|
||||||
rate where the timing constraints of the USB spec can be met.
|
rate where the timing constraints of the USB spec can be met.
|
||||||
|
|
||||||
15 MHz Clock
|
15 MHz Clock
|
||||||
@ -67,29 +67,19 @@ if you need the slightly higher clock rate for performance reasons. Since
|
|||||||
16 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code
|
16 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code
|
||||||
is somewhat tricky and has to insert a leap cycle every third byte.
|
is somewhat tricky and has to insert a leap cycle every third byte.
|
||||||
|
|
||||||
12.8 MHz and 16.5 MHz Clock
|
16.5 MHz Clock
|
||||||
The assembler modules for these clock rates differ from the other modules
|
The assembler module for this clock rate differs from the other modules because
|
||||||
because they have been built for an RC oscillator with only 1% precision. The
|
it has been built for an RC oscillator with only 1% precision. The receiver
|
||||||
receiver code inserts leap cycles to compensate for clock deviations. 1% is
|
code inserts leap cycles to compensate for clock deviations. 1% is also the
|
||||||
also the precision which can be achieved by calibrating the internal RC
|
precision which can be achieved by calibrating the internal RC oscillator of
|
||||||
oscillator of the AVR. Please note that only AVRs with internal 64 MHz PLL
|
the AVR. Please note that only AVRs with internal 64 MHz PLL oscillator can be
|
||||||
oscillator can reach 16.5 MHz with the RC oscillator. This includes the very
|
used since the 8 MHz RC oscillator cannot be trimmed up to 16.5 MHz. This
|
||||||
popular ATTiny25, ATTiny45, ATTiny85 series as well as the ATTiny26. Almost
|
includes the very popular ATTiny25, ATTiny45, ATTiny85 series as well as the
|
||||||
all AVRs can reach 12.8 MHz, although this is outside the specified range.
|
ATTiny26.
|
||||||
|
|
||||||
See the EasyLogger example at http://www.obdev.at/vusb/easylogger.html for
|
See the EasyLogger example at http://www.obdev.at/avrusb/easylogger.html for
|
||||||
code which calibrates the RC oscillator based on the USB frame clock.
|
code which calibrates the RC oscillator based on the USB frame clock.
|
||||||
|
|
||||||
18 MHz Clock
|
|
||||||
This module is closer to the USB specification because it performs an on the
|
|
||||||
fly CRC check for incoming packets. Packets with invalid checksum are
|
|
||||||
discarded as required by the spec. If you also implement checks for data
|
|
||||||
PID toggling on application level (see option USB_CFG_CHECK_DATA_TOGGLING
|
|
||||||
in usbconfig.h for more info), this ensures data integrity. Due to the CRC
|
|
||||||
tables and alignment requirements, this code is bigger than modules for other
|
|
||||||
clock rates. To activate this module, you must define USB_CFG_CHECK_CRC to 1
|
|
||||||
and USB_CFG_CLOCK_KHZ to 18000 in usbconfig.h.
|
|
||||||
|
|
||||||
20 MHz Clock
|
20 MHz Clock
|
||||||
This module is for people who won't do it with less than the maximum. Since
|
This module is for people who won't do it with less than the maximum. Since
|
||||||
20 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code
|
20 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code
|
||||||
@ -104,69 +94,53 @@ can assign PIDs at will.
|
|||||||
|
|
||||||
Since an entry level cost of 1,500 USD is too high for most small companies
|
Since an entry level cost of 1,500 USD is too high for most small companies
|
||||||
and hobbyists, we provide some VID/PID pairs for free. See the file
|
and hobbyists, we provide some VID/PID pairs for free. See the file
|
||||||
USB-IDs-for-free.txt for details.
|
USBID-License.txt for details.
|
||||||
|
|
||||||
Objective Development also has some license offerings which include product
|
Objective Development also has some license offerings which include product
|
||||||
IDs. See http://www.obdev.at/vusb/ for details.
|
IDs. See http://www.obdev.at/avrusb/ for details.
|
||||||
|
|
||||||
|
|
||||||
DEVELOPMENT SYSTEM
|
DEVELOPMENT SYSTEM
|
||||||
==================
|
==================
|
||||||
This driver has been developed and optimized for the GNU compiler version 3
|
This driver has been developed and optimized for the GNU compiler version 3
|
||||||
and 4. We recommend that you use the GNU compiler suite because it is freely
|
(gcc 3). It does work well with gcc 4, but with bigger code size. We recommend
|
||||||
available. V-USB has also been ported to the IAR compiler and assembler. It
|
that you use the GNU compiler suite because it is freely available. AVR-USB
|
||||||
has been tested with IAR 4.10B/W32 and 4.12A/W32 on an ATmega8 with the
|
has also been ported to the IAR compiler and assembler. It has been tested
|
||||||
"small" and "tiny" memory model. Not every release is tested with IAR CC and
|
with IAR 4.10B/W32 and 4.12A/W32 on an ATmega8 with the "small" and "tiny"
|
||||||
the driver may therefore fail to compile with IAR. Please note that gcc is
|
memory model. Not every release is tested with IAR CC and the driver may
|
||||||
more efficient for usbdrv.c because this module has been deliberately
|
therefore fail to compile with IAR. Please note that gcc is more efficient for
|
||||||
optimized for gcc.
|
usbdrv.c because this module has been deliberately optimized for gcc.
|
||||||
|
|
||||||
Gcc version 3 produces smaller code than version 4 due to new optimizing
|
|
||||||
capabilities which don't always improve things on 8 bit CPUs. The code size
|
|
||||||
generated by gcc 4 can be reduced with the compiler options
|
|
||||||
-fno-move-loop-invariants, -fno-tree-scev-cprop and
|
|
||||||
-fno-inline-small-functions in addition to -Os. On devices with more than
|
|
||||||
8k of flash memory, we also recommend the linker option --relax (written as
|
|
||||||
-Wl,--relax for gcc) to convert absolute calls into relative where possible.
|
|
||||||
|
|
||||||
For more information about optimizing options see:
|
|
||||||
|
|
||||||
http://www.tty1.net/blog/2008-04-29-avr-gcc-optimisations_en.html
|
|
||||||
|
|
||||||
These optimizations are good for gcc 4.x. Version 3.x of gcc does not support
|
|
||||||
most of these options and produces good code anyway.
|
|
||||||
|
|
||||||
|
|
||||||
USING V-USB FOR FREE
|
USING AVR-USB FOR FREE
|
||||||
====================
|
======================
|
||||||
The AVR firmware driver is published under the GNU General Public License
|
The AVR firmware driver is published under the GNU General Public License
|
||||||
Version 2 (GPL2) and the GNU General Public License Version 3 (GPL3). It is
|
Version 2 (GPL2). See the file "License.txt" for details.
|
||||||
your choice whether you apply the terms of version 2 or version 3.
|
|
||||||
|
|
||||||
If you decide for the free GPL2 or GPL3, we STRONGLY ENCOURAGE you to do the
|
If you decide for the free GPL2, we STRONGLY ENCOURAGE you to do the following
|
||||||
following things IN ADDITION to the obligations from the GPL:
|
things IN ADDITION to the obligations from the GPL2:
|
||||||
|
|
||||||
(1) Publish your entire project on a web site and drop us a note with the URL.
|
(1) Publish your entire project on a web site and drop us a note with the URL.
|
||||||
Use the form at http://www.obdev.at/vusb/feedback.html for your submission.
|
Use the form at http://www.obdev.at/avrusb/feedback.html for your submission.
|
||||||
If you don't have a web site, you can publish the project in obdev's
|
If you don't have a web site, you can publish the project in obdev's
|
||||||
documentation wiki at
|
documentation wiki at
|
||||||
http://www.obdev.at/goto.php?t=vusb-wiki&p=hosted-projects.
|
http://www.obdev.at/goto.php?t=avrusb-wiki&p=hosted-projects.
|
||||||
|
|
||||||
(2) Adhere to minimum publication standards. Please include AT LEAST:
|
(2) Adhere to minimum publication standards. Please include AT LEAST:
|
||||||
- a circuit diagram in PDF, PNG or GIF format
|
- a circuit diagram in PDF, PNG or GIF format
|
||||||
- full source code for the host software
|
- full source code for the host software
|
||||||
- a Readme.txt file in ASCII format which describes the purpose of the
|
- a Readme.txt file in ASCII format which describes the purpose of the
|
||||||
project and what can be found in which directories and which files
|
project and what can be found in which directories and which files
|
||||||
- a reference to http://www.obdev.at/vusb/
|
- a reference to http://www.obdev.at/avrusb/
|
||||||
|
|
||||||
(3) If you improve the driver firmware itself, please give us a free license
|
(3) If you improve the driver firmware itself, please give us a free license
|
||||||
to your modifications for our commercial license offerings.
|
to your modifications for our commercial license offerings.
|
||||||
|
|
||||||
|
|
||||||
COMMERCIAL LICENSES FOR V-USB
|
COMMERCIAL LICENSES FOR AVR-USB
|
||||||
=============================
|
===============================
|
||||||
If you don't want to publish your source code under the terms of the GPL,
|
If you don't want to publish your source code under the terms of the GPL2,
|
||||||
you can simply pay money for V-USB. As an additional benefit you get
|
you can simply pay money for AVR-USB. As an additional benefit you get
|
||||||
USB PIDs for free, reserved exclusively to you. See the file
|
USB PIDs for free, licensed exclusively to you. See the file
|
||||||
"CommercialLicense.txt" for details.
|
"CommercialLicense.txt" for details.
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
/* Name: asmcommon.inc
|
/* Name: asmcommon.inc
|
||||||
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
* Project: AVR USB driver
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2007-11-05
|
* Creation Date: 2007-11-05
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
|
||||||
|
* Revision: $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
@ -102,11 +103,8 @@ sofError:
|
|||||||
reti
|
reti
|
||||||
|
|
||||||
handleData:
|
handleData:
|
||||||
#if USB_CFG_CHECK_CRC
|
lds token, usbCurrentTok;[18]
|
||||||
CRC_CLEANUP_AND_CHECK ; jumps to ignorePacket if CRC error
|
tst token ;[20]
|
||||||
#endif
|
|
||||||
lds shift, usbCurrentTok;[18]
|
|
||||||
tst shift ;[20]
|
|
||||||
breq doReturn ;[21]
|
breq doReturn ;[21]
|
||||||
lds x2, usbRxLen ;[22]
|
lds x2, usbRxLen ;[22]
|
||||||
tst x2 ;[24]
|
tst x2 ;[24]
|
||||||
@ -115,11 +113,8 @@ handleData:
|
|||||||
; recognized if usbPoll() was called less frequently than once every 4 ms.
|
; recognized if usbPoll() was called less frequently than once every 4 ms.
|
||||||
cpi cnt, 4 ;[26] zero sized data packets are status phase only -- ignore and ack
|
cpi cnt, 4 ;[26] zero sized data packets are status phase only -- ignore and ack
|
||||||
brmi sendAckAndReti ;[27] keep rx buffer clean -- we must not NAK next SETUP
|
brmi sendAckAndReti ;[27] keep rx buffer clean -- we must not NAK next SETUP
|
||||||
#if USB_CFG_CHECK_DATA_TOGGLING
|
|
||||||
sts usbCurrentDataToken, token ; store for checking by C code
|
|
||||||
#endif
|
|
||||||
sts usbRxLen, cnt ;[28] store received data, swap buffers
|
sts usbRxLen, cnt ;[28] store received data, swap buffers
|
||||||
sts usbRxToken, shift ;[30]
|
sts usbRxToken, token ;[30]
|
||||||
lds x2, usbInputBufOffset;[32] swap buffers
|
lds x2, usbInputBufOffset;[32] swap buffers
|
||||||
ldi cnt, USB_BUFSIZE ;[34]
|
ldi cnt, USB_BUFSIZE ;[34]
|
||||||
sub cnt, x2 ;[35]
|
sub cnt, x2 ;[35]
|
||||||
@ -136,11 +131,7 @@ handleIn:
|
|||||||
ldi x1, USBPID_NAK ;[34] prepare value for usbTxLen
|
ldi x1, USBPID_NAK ;[34] prepare value for usbTxLen
|
||||||
#if USB_CFG_HAVE_INTRIN_ENDPOINT
|
#if USB_CFG_HAVE_INTRIN_ENDPOINT
|
||||||
andi x3, 0xf ;[35] x3 contains endpoint
|
andi x3, 0xf ;[35] x3 contains endpoint
|
||||||
#if USB_CFG_SUPPRESS_INTR_CODE
|
|
||||||
brne sendNakAndReti ;[36]
|
|
||||||
#else
|
|
||||||
brne handleIn1 ;[36]
|
brne handleIn1 ;[36]
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
lds cnt, usbTxLen ;[37]
|
lds cnt, usbTxLen ;[37]
|
||||||
sbrc cnt, 4 ;[39] all handshake tokens have bit 4 set
|
sbrc cnt, 4 ;[39] all handshake tokens have bit 4 set
|
||||||
@ -159,7 +150,7 @@ handleIn:
|
|||||||
; RAM this way and avoid potential problems with endless retries. The rest of
|
; RAM this way and avoid potential problems with endless retries. The rest of
|
||||||
; the driver assumes error-free transfers anyway.
|
; the driver assumes error-free transfers anyway.
|
||||||
|
|
||||||
#if !USB_CFG_SUPPRESS_INTR_CODE && USB_CFG_HAVE_INTRIN_ENDPOINT /* placed here due to relative jump range */
|
#if USB_CFG_HAVE_INTRIN_ENDPOINT /* placed here due to relative jump range */
|
||||||
handleIn1: ;[38]
|
handleIn1: ;[38]
|
||||||
#if USB_CFG_HAVE_INTRIN_ENDPOINT3
|
#if USB_CFG_HAVE_INTRIN_ENDPOINT3
|
||||||
; 2006-06-10 as suggested by O.Tamura: support second INTR IN / BULK IN endpoint
|
; 2006-06-10 as suggested by O.Tamura: support second INTR IN / BULK IN endpoint
|
||||||
@ -173,8 +164,9 @@ handleIn1: ;[38]
|
|||||||
ldi YL, lo8(usbTxBuf1) ;[46]
|
ldi YL, lo8(usbTxBuf1) ;[46]
|
||||||
ldi YH, hi8(usbTxBuf1) ;[47]
|
ldi YH, hi8(usbTxBuf1) ;[47]
|
||||||
rjmp usbSendAndReti ;[48] 50 + 12 = 62 until SOP
|
rjmp usbSendAndReti ;[48] 50 + 12 = 62 until SOP
|
||||||
|
#endif
|
||||||
|
|
||||||
#if USB_CFG_HAVE_INTRIN_ENDPOINT3
|
#if USB_CFG_HAVE_INTRIN_ENDPOINT && USB_CFG_HAVE_INTRIN_ENDPOINT3
|
||||||
handleIn3:
|
handleIn3:
|
||||||
lds cnt, usbTxLen3 ;[41]
|
lds cnt, usbTxLen3 ;[41]
|
||||||
sbrc cnt, 4 ;[43]
|
sbrc cnt, 4 ;[43]
|
||||||
@ -184,4 +176,3 @@ handleIn3:
|
|||||||
ldi YH, hi8(usbTxBuf3) ;[48]
|
ldi YH, hi8(usbTxBuf3) ;[48]
|
||||||
rjmp usbSendAndReti ;[49] 51 + 12 = 63 until SOP
|
rjmp usbSendAndReti ;[49] 51 + 12 = 63 until SOP
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|||||||
@ -4,7 +4,8 @@
|
|||||||
* Creation Date: 2005-01-16
|
* Creation Date: 2005-01-16
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: oddebug.c 275 2007-03-20 09:58:28Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "oddebug.h"
|
#include "oddebug.h"
|
||||||
|
|||||||
@ -4,7 +4,8 @@
|
|||||||
* Creation Date: 2005-01-16
|
* Creation Date: 2005-01-16
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: oddebug.h 275 2007-03-20 09:58:28Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __oddebug_h_included__
|
#ifndef __oddebug_h_included__
|
||||||
@ -28,7 +29,10 @@ the output and a memory block to dump in hex ('data' and 'len').
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* make sure we have the UART defines: */
|
/* make sure we have the UART defines: */
|
||||||
#include "usbportability.h"
|
#include "iarcompat.h"
|
||||||
|
#ifndef __IAR_SYSTEMS_ICC__
|
||||||
|
# include <avr/io.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef uchar
|
#ifndef uchar
|
||||||
# define uchar unsigned char
|
# define uchar unsigned char
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
/* Name: usbconfig.h
|
/* Name: usbconfig.h
|
||||||
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
* Project: AVR USB driver
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2005-04-01
|
* Creation Date: 2005-04-01
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: usbconfig-prototype.h 600 2008-05-13 10:34:56Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __usbconfig_h_included__
|
#ifndef __usbconfig_h_included__
|
||||||
@ -13,7 +14,7 @@
|
|||||||
/*
|
/*
|
||||||
General Description:
|
General Description:
|
||||||
This file is an example configuration (with inline documentation) for the USB
|
This file is an example configuration (with inline documentation) for the USB
|
||||||
driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
|
driver. It configures AVR-USB for USB D+ connected to Port D bit 2 (which is
|
||||||
also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
|
also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
|
||||||
wire the lines to any other port, as long as D+ is also wired to INT0 (or any
|
wire the lines to any other port, as long as D+ is also wired to INT0 (or any
|
||||||
other hardware interrupt, as long as it is the highest level interrupt, see
|
other hardware interrupt, as long as it is the highest level interrupt, see
|
||||||
@ -43,19 +44,11 @@ section at the end of this file).
|
|||||||
* markers every millisecond.]
|
* markers every millisecond.]
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
|
#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
|
||||||
/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000,
|
/* Clock rate of the AVR in MHz. Legal values are 12000, 15000, 16000, 16500
|
||||||
* 16500, 18000 and 20000. The 12.8 MHz and 16.5 MHz versions of the code
|
* and 20000. The 16.5 MHz version of the code requires no crystal, it
|
||||||
* require no crystal, they tolerate +/- 1% deviation from the nominal
|
* tolerates +/- 1% deviation from the nominal frequency. All other rates
|
||||||
* frequency. All other rates require a precision of 2000 ppm and thus a
|
* require a precision of 2000 ppm and thus a crystal!
|
||||||
* crystal!
|
* Default if not specified: 12 MHz
|
||||||
* Since F_CPU should be defined to your actual clock rate anyway, you should
|
|
||||||
* not need to modify this setting.
|
|
||||||
*/
|
|
||||||
#define USB_CFG_CHECK_CRC 0
|
|
||||||
/* Define this to 1 if you want that the driver checks integrity of incoming
|
|
||||||
* data packets (CRC checks). CRC checks cost quite a bit of code size and are
|
|
||||||
* currently only available for 18 MHz crystal clock. You must choose
|
|
||||||
* USB_CFG_CLOCK_KHZ = 18000 if you enable this option.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ----------------------- Optional Hardware Config ------------------------ */
|
/* ----------------------- Optional Hardware Config ------------------------ */
|
||||||
@ -101,14 +94,6 @@ section at the end of this file).
|
|||||||
* it is required by the standard. We have made it a config option because it
|
* it is required by the standard. We have made it a config option because it
|
||||||
* bloats the code considerably.
|
* bloats the code considerably.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_SUPPRESS_INTR_CODE 0
|
|
||||||
/* Define this to 1 if you want to declare interrupt-in endpoints, but don't
|
|
||||||
* want to send any data over them. If this macro is defined to 1, functions
|
|
||||||
* usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if
|
|
||||||
* you need the interrupt-in endpoints in order to comply to an interface
|
|
||||||
* (e.g. HID), but never want to send any data. This option saves a couple
|
|
||||||
* of bytes in flash memory and the transmit buffers in RAM.
|
|
||||||
*/
|
|
||||||
#define USB_CFG_INTR_POLL_INTERVAL 10
|
#define USB_CFG_INTR_POLL_INTERVAL 10
|
||||||
/* If you compile a version with endpoint 1 (interrupt-in), this is the poll
|
/* If you compile a version with endpoint 1 (interrupt-in), this is the poll
|
||||||
* interval. The value is in milliseconds and must not be less than 10 ms for
|
* interval. The value is in milliseconds and must not be less than 10 ms for
|
||||||
@ -145,11 +130,6 @@ section at the end of this file).
|
|||||||
* of the macros usbDisableAllRequests() and usbEnableAllRequests() in
|
* of the macros usbDisableAllRequests() and usbEnableAllRequests() in
|
||||||
* usbdrv.h.
|
* usbdrv.h.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DRIVER_FLASH_PAGE 0
|
|
||||||
/* If the device has more than 64 kBytes of flash, define this to the 64 k page
|
|
||||||
* where the driver's constants (descriptors) are located. Or in other words:
|
|
||||||
* Define this to 1 for boot loaders on the ATMega128.
|
|
||||||
*/
|
|
||||||
#define USB_CFG_LONG_TRANSFERS 0
|
#define USB_CFG_LONG_TRANSFERS 0
|
||||||
/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
|
/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
|
||||||
* in a single control-in or control-out transfer. Note that the capability
|
* in a single control-in or control-out transfer. Note that the capability
|
||||||
@ -176,67 +156,28 @@ section at the end of this file).
|
|||||||
* counts SOF packets. This feature requires that the hardware interrupt is
|
* counts SOF packets. This feature requires that the hardware interrupt is
|
||||||
* connected to D- instead of D+.
|
* connected to D- instead of D+.
|
||||||
*/
|
*/
|
||||||
/* #ifdef __ASSEMBLER__
|
|
||||||
* macro myAssemblerMacro
|
|
||||||
* in YL, TCNT0
|
|
||||||
* sts timer0Snapshot, YL
|
|
||||||
* endm
|
|
||||||
* #endif
|
|
||||||
* #define USB_SOF_HOOK myAssemblerMacro
|
|
||||||
* This macro (if defined) is executed in the assembler module when a
|
|
||||||
* Start Of Frame condition is detected. It is recommended to define it to
|
|
||||||
* the name of an assembler macro which is defined here as well so that more
|
|
||||||
* than one assembler instruction can be used. The macro may use the register
|
|
||||||
* YL and modify SREG. If it lasts longer than a couple of cycles, USB messages
|
|
||||||
* immediately after an SOF pulse may be lost and must be retried by the host.
|
|
||||||
* What can you do with this hook? Since the SOF signal occurs exactly every
|
|
||||||
* 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in
|
|
||||||
* designs running on the internal RC oscillator.
|
|
||||||
* Please note that Start Of Frame detection works only if D- is wired to the
|
|
||||||
* interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
|
|
||||||
*/
|
|
||||||
#define USB_CFG_CHECK_DATA_TOGGLING 0
|
|
||||||
/* define this macro to 1 if you want to filter out duplicate data packets
|
|
||||||
* sent by the host. Duplicates occur only as a consequence of communication
|
|
||||||
* errors, when the host does not receive an ACK. Please note that you need to
|
|
||||||
* implement the filtering yourself in usbFunctionWriteOut() and
|
|
||||||
* usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
|
|
||||||
* for each control- and out-endpoint to check for duplicate packets.
|
|
||||||
*/
|
|
||||||
#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
|
#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
|
||||||
/* define this macro to 1 if you want the function usbMeasureFrameLength()
|
/* define this macro to 1 if you want the function usbMeasureFrameLength()
|
||||||
* compiled in. This function can be used to calibrate the AVR's RC oscillator.
|
* compiled in. This function can be used to calibrate the AVR's RC oscillator.
|
||||||
*/
|
*/
|
||||||
#define USB_USE_FAST_CRC 0
|
|
||||||
/* The assembler module has two implementations for the CRC algorithm. One is
|
|
||||||
* faster, the other is smaller. This CRC routine is only used for transmitted
|
|
||||||
* messages where timing is not critical. The faster routine needs 31 cycles
|
|
||||||
* per byte while the smaller one needs 61 to 69 cycles. The faster routine
|
|
||||||
* may be worth the 32 bytes bigger code size if you transmit lots of data and
|
|
||||||
* run the AVR close to its limit.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* -------------------------- Device Description --------------------------- */
|
/* -------------------------- Device Description --------------------------- */
|
||||||
|
|
||||||
#define USB_CFG_VENDOR_ID 0xc0, 0x16 /* = 0x16c0 = 5824 = voti.nl */
|
#define USB_CFG_VENDOR_ID 0xc0, 0x16
|
||||||
/* USB vendor ID for the device, low byte first. If you have registered your
|
/* USB vendor ID for the device, low byte first. If you have registered your
|
||||||
* own Vendor ID, define it here. Otherwise you may use one of obdev's free
|
* own Vendor ID, define it here. Otherwise you use one of obdev's free shared
|
||||||
* shared VID/PID pairs. Be sure to read USB-IDs-for-free.txt for rules!
|
* VID/PID pairs. Be sure to read USBID-License.txt for rules!
|
||||||
* *** IMPORTANT NOTE ***
|
* + This template uses obdev's shared VID/PID pair: 0x16c0/0x5dc.
|
||||||
* This template uses obdev's shared VID/PID pair for Vendor Class devices
|
* + Use this VID/PID pair ONLY if you understand the implications!
|
||||||
* with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
|
|
||||||
* the implications!
|
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DEVICE_ID 0xdc, 0x05 /* = 0x05dc = 1500 */
|
#define USB_CFG_DEVICE_ID 0xdc, 0x05
|
||||||
/* This is the ID of the product, low byte first. It is interpreted in the
|
/* This is the ID of the product, low byte first. It is interpreted in the
|
||||||
* scope of the vendor ID. If you have registered your own VID with usb.org
|
* scope of the vendor ID. If you have registered your own VID with usb.org
|
||||||
* or if you have licensed a PID from somebody else, define it here. Otherwise
|
* or if you have licensed a PID from somebody else, define it here. Otherwise
|
||||||
* you may use one of obdev's free shared VID/PID pairs. See the file
|
* you use obdev's free shared VID/PID pair. Be sure to read the rules in
|
||||||
* USB-IDs-for-free.txt for details!
|
* USBID-License.txt!
|
||||||
* *** IMPORTANT NOTE ***
|
* + This template uses obdev's shared VID/PID pair: 0x16c0/0x5dc.
|
||||||
* This template uses obdev's shared VID/PID pair for Vendor Class devices
|
* + Use this VID/PID pair ONLY if you understand the implications!
|
||||||
* with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
|
|
||||||
* the implications!
|
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DEVICE_VERSION 0x00, 0x01
|
#define USB_CFG_DEVICE_VERSION 0x00, 0x01
|
||||||
/* Version number of the device: Minor number first, then major number.
|
/* Version number of the device: Minor number first, then major number.
|
||||||
@ -248,14 +189,14 @@ section at the end of this file).
|
|||||||
* are interpreted as Unicode (UTF-16) entities.
|
* are interpreted as Unicode (UTF-16) entities.
|
||||||
* If you don't want a vendor name string, undefine these macros.
|
* If you don't want a vendor name string, undefine these macros.
|
||||||
* ALWAYS define a vendor name containing your Internet domain name if you use
|
* ALWAYS define a vendor name containing your Internet domain name if you use
|
||||||
* obdev's free shared VID/PID pair. See the file USB-IDs-for-free.txt for
|
* obdev's free shared VID/PID pair. See the file USBID-License.txt for
|
||||||
* details.
|
* details.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DEVICE_NAME 'T', 'e', 'm', 'p', 'l', 'a', 't', 'e'
|
#define USB_CFG_DEVICE_NAME 'T', 'e', 'm', 'p', 'l', 'a', 't', 'e'
|
||||||
#define USB_CFG_DEVICE_NAME_LEN 8
|
#define USB_CFG_DEVICE_NAME_LEN 8
|
||||||
/* Same as above for the device name. If you don't want a device name, undefine
|
/* Same as above for the device name. If you don't want a device name, undefine
|
||||||
* the macros. See the file USB-IDs-for-free.txt before you assign a name if
|
* the macros. See the file USBID-License.txt before you assign a name if you
|
||||||
* you use a shared VID/PID.
|
* use a shared VID/PID.
|
||||||
*/
|
*/
|
||||||
/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */
|
/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */
|
||||||
/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */
|
/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */
|
||||||
@ -302,9 +243,7 @@ section at the end of this file).
|
|||||||
* no properties are defined or if they are 0, the default descriptor is used.
|
* no properties are defined or if they are 0, the default descriptor is used.
|
||||||
* Possible properties are:
|
* Possible properties are:
|
||||||
* + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
|
* + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
|
||||||
* at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is
|
* at runtime via usbFunctionDescriptor().
|
||||||
* used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if
|
|
||||||
* you want RAM pointers.
|
|
||||||
* + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
|
* + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
|
||||||
* in static memory is in RAM, not in flash memory.
|
* in static memory is in RAM, not in flash memory.
|
||||||
* + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
|
* + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
|
||||||
@ -336,12 +275,6 @@ section at the end of this file).
|
|||||||
* USB_CFG_DESCR_PROPS_HID_REPORT
|
* USB_CFG_DESCR_PROPS_HID_REPORT
|
||||||
* USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
|
* USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
|
||||||
*
|
*
|
||||||
* Note about string descriptors: String descriptors are not just strings, they
|
|
||||||
* are Unicode strings prefixed with a 2 byte header. Example:
|
|
||||||
* int serialNumberDescriptor[] = {
|
|
||||||
* USB_STRING_DESCRIPTOR_HEADER(6),
|
|
||||||
* 'S', 'e', 'r', 'i', 'a', 'l'
|
|
||||||
* };
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define USB_CFG_DESCR_PROPS_DEVICE 0
|
#define USB_CFG_DESCR_PROPS_DEVICE 0
|
||||||
@ -355,15 +288,6 @@ section at the end of this file).
|
|||||||
#define USB_CFG_DESCR_PROPS_HID_REPORT 0
|
#define USB_CFG_DESCR_PROPS_HID_REPORT 0
|
||||||
#define USB_CFG_DESCR_PROPS_UNKNOWN 0
|
#define USB_CFG_DESCR_PROPS_UNKNOWN 0
|
||||||
|
|
||||||
|
|
||||||
#define usbMsgPtr_t unsigned short
|
|
||||||
/* If usbMsgPtr_t is not defined, it defaults to 'uchar *'. We define it to
|
|
||||||
* a scalar type here because gcc generates slightly shorter code for scalar
|
|
||||||
* arithmetics than for pointer arithmetics. Remove this define for backward
|
|
||||||
* type compatibility or define it to an 8 bit type if you use data in RAM only
|
|
||||||
* and all RAM is below 256 bytes (tiny memory model in IAR CC).
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ----------------------- Optional MCU Description ------------------------ */
|
/* ----------------------- Optional MCU Description ------------------------ */
|
||||||
|
|
||||||
/* The following configurations have working defaults in usbdrv.h. You
|
/* The following configurations have working defaults in usbdrv.h. You
|
||||||
@ -379,6 +303,6 @@ section at the end of this file).
|
|||||||
/* #define USB_INTR_ENABLE_BIT INT0 */
|
/* #define USB_INTR_ENABLE_BIT INT0 */
|
||||||
/* #define USB_INTR_PENDING GIFR */
|
/* #define USB_INTR_PENDING GIFR */
|
||||||
/* #define USB_INTR_PENDING_BIT INTF0 */
|
/* #define USB_INTR_PENDING_BIT INTF0 */
|
||||||
/* #define USB_INTR_VECTOR INT0_vect */
|
/* #define USB_INTR_VECTOR SIG_INTERRUPT0 */
|
||||||
|
|
||||||
#endif /* __usbconfig_h_included__ */
|
#endif /* __usbconfig_h_included__ */
|
||||||
|
|||||||
@ -1,12 +1,18 @@
|
|||||||
/* Name: usbdrv.c
|
/* Name: usbdrv.c
|
||||||
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
* Project: AVR USB driver
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2004-12-29
|
* Creation Date: 2004-12-29
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: usbdrv.c 591 2008-05-03 20:21:19Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "iarcompat.h"
|
||||||
|
#ifndef __IAR_SYSTEMS_ICC__
|
||||||
|
# include <avr/io.h>
|
||||||
|
# include <avr/pgmspace.h>
|
||||||
|
#endif
|
||||||
#include "usbdrv.h"
|
#include "usbdrv.h"
|
||||||
#include "oddebug.h"
|
#include "oddebug.h"
|
||||||
|
|
||||||
@ -32,18 +38,15 @@ uchar usbTxBuf[USB_BUFSIZE];/* data to transmit with next IN, free if usbT
|
|||||||
#if USB_COUNT_SOF
|
#if USB_COUNT_SOF
|
||||||
volatile uchar usbSofCount; /* incremented by assembler module every SOF */
|
volatile uchar usbSofCount; /* incremented by assembler module every SOF */
|
||||||
#endif
|
#endif
|
||||||
#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE
|
#if USB_CFG_HAVE_INTRIN_ENDPOINT
|
||||||
usbTxStatus_t usbTxStatus1;
|
usbTxStatus_t usbTxStatus1;
|
||||||
# if USB_CFG_HAVE_INTRIN_ENDPOINT3
|
# if USB_CFG_HAVE_INTRIN_ENDPOINT3
|
||||||
usbTxStatus_t usbTxStatus3;
|
usbTxStatus_t usbTxStatus3;
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#if USB_CFG_CHECK_DATA_TOGGLING
|
|
||||||
uchar usbCurrentDataToken;/* when we check data toggling to ignore duplicate packets */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* USB status registers / not shared with asm code */
|
/* USB status registers / not shared with asm code */
|
||||||
usbMsgPtr_t usbMsgPtr; /* data to transmit next -- ROM or RAM address */
|
uchar *usbMsgPtr; /* data to transmit next -- ROM or RAM address */
|
||||||
static usbMsgLen_t usbMsgLen = USB_NO_MSG; /* remaining number of bytes */
|
static usbMsgLen_t usbMsgLen = USB_NO_MSG; /* remaining number of bytes */
|
||||||
static uchar usbMsgFlags; /* flag values see below */
|
static uchar usbMsgFlags; /* flag values see below */
|
||||||
|
|
||||||
@ -53,7 +56,7 @@ static uchar usbMsgFlags; /* flag values see below */
|
|||||||
/*
|
/*
|
||||||
optimizing hints:
|
optimizing hints:
|
||||||
- do not post/pre inc/dec integer values in operations
|
- do not post/pre inc/dec integer values in operations
|
||||||
- assign value of USB_READ_FLASH() to register variables and don't use side effects in arg
|
- assign value of PRG_RDB() to register variables and don't use side effects in arg
|
||||||
- use narrow scope for variables which should be in X/Y/Z register
|
- use narrow scope for variables which should be in X/Y/Z register
|
||||||
- assign char sized expressions to variables to force 8 bit arithmetics
|
- assign char sized expressions to variables to force 8 bit arithmetics
|
||||||
*/
|
*/
|
||||||
@ -65,7 +68,7 @@ optimizing hints:
|
|||||||
#if USB_CFG_DESCR_PROPS_STRING_0 == 0
|
#if USB_CFG_DESCR_PROPS_STRING_0 == 0
|
||||||
#undef USB_CFG_DESCR_PROPS_STRING_0
|
#undef USB_CFG_DESCR_PROPS_STRING_0
|
||||||
#define USB_CFG_DESCR_PROPS_STRING_0 sizeof(usbDescriptorString0)
|
#define USB_CFG_DESCR_PROPS_STRING_0 sizeof(usbDescriptorString0)
|
||||||
PROGMEM const char usbDescriptorString0[] = { /* language descriptor */
|
PROGMEM char usbDescriptorString0[] = { /* language descriptor */
|
||||||
4, /* sizeof(usbDescriptorString0): length of descriptor in bytes */
|
4, /* sizeof(usbDescriptorString0): length of descriptor in bytes */
|
||||||
3, /* descriptor type */
|
3, /* descriptor type */
|
||||||
0x09, 0x04, /* language index (0x0409 = US-English) */
|
0x09, 0x04, /* language index (0x0409 = US-English) */
|
||||||
@ -75,7 +78,7 @@ PROGMEM const char usbDescriptorString0[] = { /* language descriptor */
|
|||||||
#if USB_CFG_DESCR_PROPS_STRING_VENDOR == 0 && USB_CFG_VENDOR_NAME_LEN
|
#if USB_CFG_DESCR_PROPS_STRING_VENDOR == 0 && USB_CFG_VENDOR_NAME_LEN
|
||||||
#undef USB_CFG_DESCR_PROPS_STRING_VENDOR
|
#undef USB_CFG_DESCR_PROPS_STRING_VENDOR
|
||||||
#define USB_CFG_DESCR_PROPS_STRING_VENDOR sizeof(usbDescriptorStringVendor)
|
#define USB_CFG_DESCR_PROPS_STRING_VENDOR sizeof(usbDescriptorStringVendor)
|
||||||
PROGMEM const int usbDescriptorStringVendor[] = {
|
PROGMEM int usbDescriptorStringVendor[] = {
|
||||||
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_VENDOR_NAME_LEN),
|
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_VENDOR_NAME_LEN),
|
||||||
USB_CFG_VENDOR_NAME
|
USB_CFG_VENDOR_NAME
|
||||||
};
|
};
|
||||||
@ -84,7 +87,7 @@ PROGMEM const int usbDescriptorStringVendor[] = {
|
|||||||
#if USB_CFG_DESCR_PROPS_STRING_PRODUCT == 0 && USB_CFG_DEVICE_NAME_LEN
|
#if USB_CFG_DESCR_PROPS_STRING_PRODUCT == 0 && USB_CFG_DEVICE_NAME_LEN
|
||||||
#undef USB_CFG_DESCR_PROPS_STRING_PRODUCT
|
#undef USB_CFG_DESCR_PROPS_STRING_PRODUCT
|
||||||
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT sizeof(usbDescriptorStringDevice)
|
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT sizeof(usbDescriptorStringDevice)
|
||||||
PROGMEM const int usbDescriptorStringDevice[] = {
|
PROGMEM int usbDescriptorStringDevice[] = {
|
||||||
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_DEVICE_NAME_LEN),
|
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_DEVICE_NAME_LEN),
|
||||||
USB_CFG_DEVICE_NAME
|
USB_CFG_DEVICE_NAME
|
||||||
};
|
};
|
||||||
@ -93,7 +96,7 @@ PROGMEM const int usbDescriptorStringDevice[] = {
|
|||||||
#if USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER == 0 && USB_CFG_SERIAL_NUMBER_LEN
|
#if USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER == 0 && USB_CFG_SERIAL_NUMBER_LEN
|
||||||
#undef USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
|
#undef USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
|
||||||
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER sizeof(usbDescriptorStringSerialNumber)
|
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER sizeof(usbDescriptorStringSerialNumber)
|
||||||
PROGMEM const int usbDescriptorStringSerialNumber[] = {
|
PROGMEM int usbDescriptorStringSerialNumber[] = {
|
||||||
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_SERIAL_NUMBER_LEN),
|
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_SERIAL_NUMBER_LEN),
|
||||||
USB_CFG_SERIAL_NUMBER
|
USB_CFG_SERIAL_NUMBER
|
||||||
};
|
};
|
||||||
@ -106,7 +109,7 @@ PROGMEM const int usbDescriptorStringSerialNumber[] = {
|
|||||||
#if USB_CFG_DESCR_PROPS_DEVICE == 0
|
#if USB_CFG_DESCR_PROPS_DEVICE == 0
|
||||||
#undef USB_CFG_DESCR_PROPS_DEVICE
|
#undef USB_CFG_DESCR_PROPS_DEVICE
|
||||||
#define USB_CFG_DESCR_PROPS_DEVICE sizeof(usbDescriptorDevice)
|
#define USB_CFG_DESCR_PROPS_DEVICE sizeof(usbDescriptorDevice)
|
||||||
PROGMEM const char usbDescriptorDevice[] = { /* USB device descriptor */
|
PROGMEM char usbDescriptorDevice[] = { /* USB device descriptor */
|
||||||
18, /* sizeof(usbDescriptorDevice): length of descriptor in bytes */
|
18, /* sizeof(usbDescriptorDevice): length of descriptor in bytes */
|
||||||
USBDESCR_DEVICE, /* descriptor type */
|
USBDESCR_DEVICE, /* descriptor type */
|
||||||
0x10, 0x01, /* USB version supported */
|
0x10, 0x01, /* USB version supported */
|
||||||
@ -137,7 +140,7 @@ PROGMEM const char usbDescriptorDevice[] = { /* USB device descriptor */
|
|||||||
#if USB_CFG_DESCR_PROPS_CONFIGURATION == 0
|
#if USB_CFG_DESCR_PROPS_CONFIGURATION == 0
|
||||||
#undef USB_CFG_DESCR_PROPS_CONFIGURATION
|
#undef USB_CFG_DESCR_PROPS_CONFIGURATION
|
||||||
#define USB_CFG_DESCR_PROPS_CONFIGURATION sizeof(usbDescriptorConfiguration)
|
#define USB_CFG_DESCR_PROPS_CONFIGURATION sizeof(usbDescriptorConfiguration)
|
||||||
PROGMEM const char usbDescriptorConfiguration[] = { /* USB configuration descriptor */
|
PROGMEM char usbDescriptorConfiguration[] = { /* USB configuration descriptor */
|
||||||
9, /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */
|
9, /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */
|
||||||
USBDESCR_CONFIG, /* descriptor type */
|
USBDESCR_CONFIG, /* descriptor type */
|
||||||
18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT3 +
|
18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT3 +
|
||||||
@ -147,9 +150,9 @@ PROGMEM const char usbDescriptorConfiguration[] = { /* USB configuration desc
|
|||||||
1, /* index of this configuration */
|
1, /* index of this configuration */
|
||||||
0, /* configuration name string index */
|
0, /* configuration name string index */
|
||||||
#if USB_CFG_IS_SELF_POWERED
|
#if USB_CFG_IS_SELF_POWERED
|
||||||
(1 << 7) | USBATTR_SELFPOWER, /* attributes */
|
USBATTR_SELFPOWER, /* attributes */
|
||||||
#else
|
#else
|
||||||
(1 << 7), /* attributes */
|
(char)USBATTR_BUSPOWER, /* attributes */
|
||||||
#endif
|
#endif
|
||||||
USB_CFG_MAX_BUS_POWER/2, /* max USB current in 2mA units */
|
USB_CFG_MAX_BUS_POWER/2, /* max USB current in 2mA units */
|
||||||
/* interface descriptor follows inline: */
|
/* interface descriptor follows inline: */
|
||||||
@ -182,7 +185,7 @@ PROGMEM const char usbDescriptorConfiguration[] = { /* USB configuration desc
|
|||||||
#if USB_CFG_HAVE_INTRIN_ENDPOINT3 /* endpoint descriptor for endpoint 3 */
|
#if USB_CFG_HAVE_INTRIN_ENDPOINT3 /* endpoint descriptor for endpoint 3 */
|
||||||
7, /* sizeof(usbDescrEndpoint) */
|
7, /* sizeof(usbDescrEndpoint) */
|
||||||
USBDESCR_ENDPOINT, /* descriptor type = endpoint */
|
USBDESCR_ENDPOINT, /* descriptor type = endpoint */
|
||||||
(char)(0x80 | USB_CFG_EP3_NUMBER), /* IN endpoint number 3 */
|
(char)0x83, /* IN endpoint number 1 */
|
||||||
0x03, /* attrib: Interrupt endpoint */
|
0x03, /* attrib: Interrupt endpoint */
|
||||||
8, 0, /* maximum packet size */
|
8, 0, /* maximum packet size */
|
||||||
USB_CFG_INTR_POLL_INTERVAL, /* in ms */
|
USB_CFG_INTR_POLL_INTERVAL, /* in ms */
|
||||||
@ -192,9 +195,18 @@ PROGMEM const char usbDescriptorConfiguration[] = { /* USB configuration desc
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* We don't use prog_int or prog_int16_t for compatibility with various libc
|
||||||
|
* versions. Here's an other compatibility hack:
|
||||||
|
*/
|
||||||
|
#ifndef PRG_RDB
|
||||||
|
#define PRG_RDB(addr) pgm_read_byte(addr)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static inline void usbResetDataToggling(void)
|
static inline void usbResetDataToggling(void)
|
||||||
{
|
{
|
||||||
#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE
|
#if USB_CFG_HAVE_INTRIN_ENDPOINT
|
||||||
USB_SET_DATATOKEN1(USB_INITIAL_DATATOKEN); /* reset data toggling for interrupt endpoint */
|
USB_SET_DATATOKEN1(USB_INITIAL_DATATOKEN); /* reset data toggling for interrupt endpoint */
|
||||||
# if USB_CFG_HAVE_INTRIN_ENDPOINT3
|
# if USB_CFG_HAVE_INTRIN_ENDPOINT3
|
||||||
USB_SET_DATATOKEN3(USB_INITIAL_DATATOKEN); /* reset data toggling for interrupt endpoint */
|
USB_SET_DATATOKEN3(USB_INITIAL_DATATOKEN); /* reset data toggling for interrupt endpoint */
|
||||||
@ -214,7 +226,6 @@ static inline void usbResetStall(void)
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#if !USB_CFG_SUPPRESS_INTR_CODE
|
|
||||||
#if USB_CFG_HAVE_INTRIN_ENDPOINT
|
#if USB_CFG_HAVE_INTRIN_ENDPOINT
|
||||||
static void usbGenericSetInterrupt(uchar *data, uchar len, usbTxStatus_t *txStatus)
|
static void usbGenericSetInterrupt(uchar *data, uchar len, usbTxStatus_t *txStatus)
|
||||||
{
|
{
|
||||||
@ -252,7 +263,6 @@ USB_PUBLIC void usbSetInterrupt3(uchar *data, uchar len)
|
|||||||
usbGenericSetInterrupt(data, len, &usbTxStatus3);
|
usbGenericSetInterrupt(data, len, &usbTxStatus3);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* USB_CFG_SUPPRESS_INTR_CODE */
|
|
||||||
|
|
||||||
/* ------------------ utilities for code following below ------------------- */
|
/* ------------------ utilities for code following below ------------------- */
|
||||||
|
|
||||||
@ -299,7 +309,7 @@ USB_PUBLIC void usbSetInterrupt3(uchar *data, uchar len)
|
|||||||
len = usbFunctionDescriptor(rq); \
|
len = usbFunctionDescriptor(rq); \
|
||||||
}else{ \
|
}else{ \
|
||||||
len = USB_PROP_LENGTH(cfgProp); \
|
len = USB_PROP_LENGTH(cfgProp); \
|
||||||
usbMsgPtr = (usbMsgPtr_t)(staticName); \
|
usbMsgPtr = (uchar *)(staticName); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,8 +369,7 @@ uchar flags = USB_FLG_MSGPTR_IS_ROM;
|
|||||||
*/
|
*/
|
||||||
static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq)
|
static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq)
|
||||||
{
|
{
|
||||||
usbMsgLen_t len = 0;
|
uchar len = 0, *dataPtr = usbTxBuf + 9; /* there are 2 bytes free space at the end of the buffer */
|
||||||
uchar *dataPtr = usbTxBuf + 9; /* there are 2 bytes free space at the end of the buffer */
|
|
||||||
uchar value = rq->wValue.bytes[0];
|
uchar value = rq->wValue.bytes[0];
|
||||||
#if USB_CFG_IMPLEMENT_HALT
|
#if USB_CFG_IMPLEMENT_HALT
|
||||||
uchar index = rq->wIndex.bytes[0];
|
uchar index = rq->wIndex.bytes[0];
|
||||||
@ -399,7 +408,7 @@ uchar index = rq->wIndex.bytes[0];
|
|||||||
usbResetStall();
|
usbResetStall();
|
||||||
SWITCH_CASE(USBRQ_GET_INTERFACE) /* 10 */
|
SWITCH_CASE(USBRQ_GET_INTERFACE) /* 10 */
|
||||||
len = 1;
|
len = 1;
|
||||||
#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE
|
#if USB_CFG_HAVE_INTRIN_ENDPOINT
|
||||||
SWITCH_CASE(USBRQ_SET_INTERFACE) /* 11 */
|
SWITCH_CASE(USBRQ_SET_INTERFACE) /* 11 */
|
||||||
usbResetDataToggling();
|
usbResetDataToggling();
|
||||||
usbResetStall();
|
usbResetStall();
|
||||||
@ -407,7 +416,7 @@ uchar index = rq->wIndex.bytes[0];
|
|||||||
SWITCH_DEFAULT /* 7=SET_DESCRIPTOR, 12=SYNC_FRAME */
|
SWITCH_DEFAULT /* 7=SET_DESCRIPTOR, 12=SYNC_FRAME */
|
||||||
/* Should we add an optional hook here? */
|
/* Should we add an optional hook here? */
|
||||||
SWITCH_END
|
SWITCH_END
|
||||||
usbMsgPtr = (usbMsgPtr_t)dataPtr;
|
usbMsgPtr = dataPtr;
|
||||||
skipMsgPtrAssignment:
|
skipMsgPtrAssignment:
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@ -427,7 +436,7 @@ usbRequest_t *rq = (void *)data;
|
|||||||
* 0xe1 11100001 (USBPID_OUT: data phase of setup transfer)
|
* 0xe1 11100001 (USBPID_OUT: data phase of setup transfer)
|
||||||
* 0...0x0f for OUT on endpoint X
|
* 0...0x0f for OUT on endpoint X
|
||||||
*/
|
*/
|
||||||
DBG2(0x10 + (usbRxToken & 0xf), data, len + 2); /* SETUP=1d, SETUP-DATA=11, OUTx=1x */
|
DBG2(0x10 + (usbRxToken & 0xf), data, len); /* SETUP=1d, SETUP-DATA=11, OUTx=1x */
|
||||||
USB_RX_USER_HOOK(data, len)
|
USB_RX_USER_HOOK(data, len)
|
||||||
#if USB_CFG_IMPLEMENT_FN_WRITEOUT
|
#if USB_CFG_IMPLEMENT_FN_WRITEOUT
|
||||||
if(usbRxToken < 0x10){ /* OUT to endpoint != 0: endpoint number in usbRxToken */
|
if(usbRxToken < 0x10){ /* OUT to endpoint != 0: endpoint number in usbRxToken */
|
||||||
@ -450,13 +459,9 @@ usbRequest_t *rq = (void *)data;
|
|||||||
}
|
}
|
||||||
#if USB_CFG_IMPLEMENT_FN_READ || USB_CFG_IMPLEMENT_FN_WRITE
|
#if USB_CFG_IMPLEMENT_FN_READ || USB_CFG_IMPLEMENT_FN_WRITE
|
||||||
if(replyLen == USB_NO_MSG){ /* use user-supplied read/write function */
|
if(replyLen == USB_NO_MSG){ /* use user-supplied read/write function */
|
||||||
/* do some conditioning on replyLen, but on IN transfers only */
|
/* do some conditioning on replyLen */
|
||||||
if((rq->bmRequestType & USBRQ_DIR_MASK) != USBRQ_DIR_HOST_TO_DEVICE){
|
if((rq->bmRequestType & USBRQ_DIR_MASK) != USBRQ_DIR_HOST_TO_DEVICE){
|
||||||
if(sizeof(replyLen) < sizeof(rq->wLength.word)){ /* help compiler with optimizing */
|
replyLen = rq->wLength.bytes[0]; /* IN transfers only */
|
||||||
replyLen = rq->wLength.bytes[0];
|
|
||||||
}else{
|
|
||||||
replyLen = rq->wLength.word;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
usbMsgFlags = USB_FLG_USE_USER_RW;
|
usbMsgFlags = USB_FLG_USE_USER_RW;
|
||||||
}else /* The 'else' prevents that we limit a replyLen of USB_NO_MSG to the maximum transfer len. */
|
}else /* The 'else' prevents that we limit a replyLen of USB_NO_MSG to the maximum transfer len. */
|
||||||
@ -497,18 +502,16 @@ static uchar usbDeviceRead(uchar *data, uchar len)
|
|||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
uchar i = len;
|
uchar i = len, *r = usbMsgPtr;
|
||||||
usbMsgPtr_t r = usbMsgPtr;
|
|
||||||
if(usbMsgFlags & USB_FLG_MSGPTR_IS_ROM){ /* ROM data */
|
if(usbMsgFlags & USB_FLG_MSGPTR_IS_ROM){ /* ROM data */
|
||||||
do{
|
do{
|
||||||
uchar c = USB_READ_FLASH(r); /* assign to char size variable to enforce byte ops */
|
uchar c = PRG_RDB(r); /* assign to char size variable to enforce byte ops */
|
||||||
*data++ = c;
|
*data++ = c;
|
||||||
r++;
|
r++;
|
||||||
}while(--i);
|
}while(--i);
|
||||||
}else{ /* RAM data */
|
}else{ /* RAM data */
|
||||||
do{
|
do{
|
||||||
*data++ = *((uchar *)r);
|
*data++ = *r++;
|
||||||
r++;
|
|
||||||
}while(--i);
|
}while(--i);
|
||||||
}
|
}
|
||||||
usbMsgPtr = r;
|
usbMsgPtr = r;
|
||||||
@ -558,8 +561,6 @@ uchar isReset = !notResetState;
|
|||||||
USB_RESET_HOOK(isReset);
|
USB_RESET_HOOK(isReset);
|
||||||
wasReset = isReset;
|
wasReset = isReset;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
notResetState = notResetState; // avoid compiler warning
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -591,17 +592,17 @@ uchar i;
|
|||||||
usbBuildTxBlock();
|
usbBuildTxBlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(i = 20; i > 0; i--){
|
for(i = 10; i > 0; i--){
|
||||||
uchar usbLineStatus = USBIN & USBMASK;
|
uchar usbLineStatus = USBIN & USBMASK;
|
||||||
if(usbLineStatus != 0) /* SE0 has ended */
|
if(usbLineStatus != 0) /* SE0 has ended */
|
||||||
goto isNotReset;
|
break;
|
||||||
}
|
}
|
||||||
/* RESET condition, called multiple times during reset */
|
if(i == 0){ /* RESET condition, called multiple times during reset */
|
||||||
usbNewDeviceAddr = 0;
|
usbNewDeviceAddr = 0;
|
||||||
usbDeviceAddr = 0;
|
usbDeviceAddr = 0;
|
||||||
usbResetStall();
|
usbResetStall();
|
||||||
DBG1(0xff, 0, 0);
|
DBG1(0xff, 0, 0);
|
||||||
isNotReset:
|
}
|
||||||
usbHandleResetHook(i);
|
usbHandleResetHook(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,7 +618,7 @@ USB_PUBLIC void usbInit(void)
|
|||||||
#endif
|
#endif
|
||||||
USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
|
USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
|
||||||
usbResetDataToggling();
|
usbResetDataToggling();
|
||||||
#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE
|
#if USB_CFG_HAVE_INTRIN_ENDPOINT
|
||||||
usbTxLen1 = USBPID_NAK;
|
usbTxLen1 = USBPID_NAK;
|
||||||
#if USB_CFG_HAVE_INTRIN_ENDPOINT3
|
#if USB_CFG_HAVE_INTRIN_ENDPOINT3
|
||||||
usbTxLen3 = USBPID_NAK;
|
usbTxLen3 = USBPID_NAK;
|
||||||
|
|||||||
@ -1,16 +1,17 @@
|
|||||||
/* Name: usbdrv.h
|
/* Name: usbdrv.h
|
||||||
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
* Project: AVR USB driver
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2004-12-29
|
* Creation Date: 2004-12-29
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: usbdrv.h 607 2008-05-13 15:57:28Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __usbdrv_h_included__
|
#ifndef __usbdrv_h_included__
|
||||||
#define __usbdrv_h_included__
|
#define __usbdrv_h_included__
|
||||||
#include "usbconfig.h"
|
#include "usbconfig.h"
|
||||||
#include "usbportability.h"
|
#include "iarcompat.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Hardware Prerequisites:
|
Hardware Prerequisites:
|
||||||
@ -33,8 +34,8 @@ usbDeviceConnect() and usbDeviceDisconnect() further down in this file.
|
|||||||
|
|
||||||
Please adapt the values in usbconfig.h according to your hardware!
|
Please adapt the values in usbconfig.h according to your hardware!
|
||||||
|
|
||||||
The device MUST be clocked at exactly 12 MHz, 15 MHz, 16 MHz or 20 MHz
|
The device MUST be clocked at exactly 12 MHz, 15 MHz or 16 MHz
|
||||||
or at 12.8 MHz resp. 16.5 MHz +/- 1%. See usbconfig-prototype.h for details.
|
or at 16.5 MHz +/- 1%. See usbconfig-prototype.h for details.
|
||||||
|
|
||||||
|
|
||||||
Limitations:
|
Limitations:
|
||||||
@ -104,9 +105,9 @@ interrupt routine.
|
|||||||
Interrupt latency:
|
Interrupt latency:
|
||||||
The application must ensure that the USB interrupt is not disabled for more
|
The application must ensure that the USB interrupt is not disabled for more
|
||||||
than 25 cycles (this is for 12 MHz, faster clocks allow longer latency).
|
than 25 cycles (this is for 12 MHz, faster clocks allow longer latency).
|
||||||
This implies that all interrupt routines must either have the "ISR_NOBLOCK"
|
This implies that all interrupt routines must either be declared as "INTERRUPT"
|
||||||
attribute set (see "avr/interrupt.h") or be written in assembler with "sei"
|
instead of "SIGNAL" (see "avr/signal.h") or that they are written in assembler
|
||||||
as the first instruction.
|
with "sei" as the first instruction.
|
||||||
|
|
||||||
Maximum interrupt duration / CPU cycle consumption:
|
Maximum interrupt duration / CPU cycle consumption:
|
||||||
The driver handles all USB communication during the interrupt service
|
The driver handles all USB communication during the interrupt service
|
||||||
@ -121,7 +122,7 @@ USB messages, even if they address another (low-speed) device on the same bus.
|
|||||||
/* --------------------------- Module Interface ---------------------------- */
|
/* --------------------------- Module Interface ---------------------------- */
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#define USBDRV_VERSION 20121206
|
#define USBDRV_VERSION 20080513
|
||||||
/* This define uniquely identifies a driver version. It is a decimal number
|
/* This define uniquely identifies a driver version. It is a decimal number
|
||||||
* constructed from the driver's release date in the form YYYYMMDD. If the
|
* constructed from the driver's release date in the form YYYYMMDD. If the
|
||||||
* driver's behavior or interface changes, you can use this constant to
|
* driver's behavior or interface changes, you can use this constant to
|
||||||
@ -162,24 +163,11 @@ USB messages, even if they address another (low-speed) device on the same bus.
|
|||||||
*/
|
*/
|
||||||
#define USB_NO_MSG ((usbMsgLen_t)-1) /* constant meaning "no message" */
|
#define USB_NO_MSG ((usbMsgLen_t)-1) /* constant meaning "no message" */
|
||||||
|
|
||||||
#ifndef usbMsgPtr_t
|
|
||||||
#define usbMsgPtr_t uchar *
|
|
||||||
#endif
|
|
||||||
/* Making usbMsgPtr_t a define allows the user of this library to define it to
|
|
||||||
* an 8 bit type on tiny devices. This reduces code size, especially if the
|
|
||||||
* compiler supports a tiny memory model.
|
|
||||||
* The type can be a pointer or scalar type, casts are made where necessary.
|
|
||||||
* Although it's paradoxical, Gcc 4 generates slightly better code for scalar
|
|
||||||
* types than for pointers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct usbRequest; /* forward declaration */
|
struct usbRequest; /* forward declaration */
|
||||||
|
|
||||||
USB_PUBLIC void usbInit(void);
|
USB_PUBLIC void usbInit(void);
|
||||||
/* This function must be called before interrupts are enabled and the main
|
/* This function must be called before interrupts are enabled and the main
|
||||||
* loop is entered. We exepct that the PORT and DDR bits for D+ and D- have
|
* loop is entered.
|
||||||
* not been changed from their default status (which is 0). If you have changed
|
|
||||||
* them, set both back to 0 (configure them as input with no internal pull-up).
|
|
||||||
*/
|
*/
|
||||||
USB_PUBLIC void usbPoll(void);
|
USB_PUBLIC void usbPoll(void);
|
||||||
/* This function must be called at regular intervals from the main loop.
|
/* This function must be called at regular intervals from the main loop.
|
||||||
@ -188,7 +176,7 @@ USB_PUBLIC void usbPoll(void);
|
|||||||
* Please note that debug outputs through the UART take ~ 0.5ms per byte
|
* Please note that debug outputs through the UART take ~ 0.5ms per byte
|
||||||
* at 19200 bps.
|
* at 19200 bps.
|
||||||
*/
|
*/
|
||||||
extern usbMsgPtr_t usbMsgPtr;
|
extern uchar *usbMsgPtr;
|
||||||
/* This variable may be used to pass transmit data to the driver from the
|
/* This variable may be used to pass transmit data to the driver from the
|
||||||
* implementation of usbFunctionWrite(). It is also used internally by the
|
* implementation of usbFunctionWrite(). It is also used internally by the
|
||||||
* driver for standard control requests.
|
* driver for standard control requests.
|
||||||
@ -285,8 +273,6 @@ USB_PUBLIC uchar usbFunctionRead(uchar *data, uchar len);
|
|||||||
* to 1 in usbconfig.h and return 0xff in usbFunctionSetup()..
|
* to 1 in usbconfig.h and return 0xff in usbFunctionSetup()..
|
||||||
*/
|
*/
|
||||||
#endif /* USB_CFG_IMPLEMENT_FN_READ */
|
#endif /* USB_CFG_IMPLEMENT_FN_READ */
|
||||||
|
|
||||||
extern uchar usbRxToken; /* may be used in usbFunctionWriteOut() below */
|
|
||||||
#if USB_CFG_IMPLEMENT_FN_WRITEOUT
|
#if USB_CFG_IMPLEMENT_FN_WRITEOUT
|
||||||
USB_PUBLIC void usbFunctionWriteOut(uchar *data, uchar len);
|
USB_PUBLIC void usbFunctionWriteOut(uchar *data, uchar len);
|
||||||
/* This function is called by the driver when data is received on an interrupt-
|
/* This function is called by the driver when data is received on an interrupt-
|
||||||
@ -353,12 +339,6 @@ extern volatile uchar usbSofCount;
|
|||||||
* the macro USB_COUNT_SOF is defined to a value != 0.
|
* the macro USB_COUNT_SOF is defined to a value != 0.
|
||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
#if USB_CFG_CHECK_DATA_TOGGLING
|
|
||||||
extern uchar usbCurrentDataToken;
|
|
||||||
/* This variable can be checked in usbFunctionWrite() and usbFunctionWriteOut()
|
|
||||||
* to ignore duplicate packets.
|
|
||||||
*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define USB_STRING_DESCRIPTOR_HEADER(stringLength) ((2*(stringLength)+2) | (3<<8))
|
#define USB_STRING_DESCRIPTOR_HEADER(stringLength) ((2*(stringLength)+2) | (3<<8))
|
||||||
/* This macro builds a descriptor header for a string descriptor given the
|
/* This macro builds a descriptor header for a string descriptor given the
|
||||||
@ -400,13 +380,11 @@ extern volatile schar usbRxLen;
|
|||||||
* about the various methods to define USB descriptors. If you do nothing,
|
* about the various methods to define USB descriptors. If you do nothing,
|
||||||
* the default descriptors will be used.
|
* the default descriptors will be used.
|
||||||
*/
|
*/
|
||||||
#define USB_PROP_IS_DYNAMIC (1u << 14)
|
#define USB_PROP_IS_DYNAMIC (1 << 14)
|
||||||
/* If this property is set for a descriptor, usbFunctionDescriptor() will be
|
/* If this property is set for a descriptor, usbFunctionDescriptor() will be
|
||||||
* used to obtain the particular descriptor. Data directly returned via
|
* used to obtain the particular descriptor.
|
||||||
* usbMsgPtr are FLASH data by default, combine (OR) with USB_PROP_IS_RAM to
|
|
||||||
* return RAM data.
|
|
||||||
*/
|
*/
|
||||||
#define USB_PROP_IS_RAM (1u << 15)
|
#define USB_PROP_IS_RAM (1 << 15)
|
||||||
/* If this property is set for a descriptor, the data is read from RAM
|
/* If this property is set for a descriptor, the data is read from RAM
|
||||||
* memory instead of Flash. The property is used for all methods to provide
|
* memory instead of Flash. The property is used for all methods to provide
|
||||||
* external descriptors.
|
* external descriptors.
|
||||||
@ -460,43 +438,43 @@ extern volatile schar usbRxLen;
|
|||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
extern
|
extern
|
||||||
#if !(USB_CFG_DESCR_PROPS_DEVICE & USB_PROP_IS_RAM)
|
#if !(USB_CFG_DESCR_PROPS_DEVICE & USB_PROP_IS_RAM)
|
||||||
PROGMEM const
|
PROGMEM
|
||||||
#endif
|
#endif
|
||||||
char usbDescriptorDevice[];
|
char usbDescriptorDevice[];
|
||||||
|
|
||||||
extern
|
extern
|
||||||
#if !(USB_CFG_DESCR_PROPS_CONFIGURATION & USB_PROP_IS_RAM)
|
#if !(USB_CFG_DESCR_PROPS_CONFIGURATION & USB_PROP_IS_RAM)
|
||||||
PROGMEM const
|
PROGMEM
|
||||||
#endif
|
#endif
|
||||||
char usbDescriptorConfiguration[];
|
char usbDescriptorConfiguration[];
|
||||||
|
|
||||||
extern
|
extern
|
||||||
#if !(USB_CFG_DESCR_PROPS_HID_REPORT & USB_PROP_IS_RAM)
|
#if !(USB_CFG_DESCR_PROPS_HID_REPORT & USB_PROP_IS_RAM)
|
||||||
PROGMEM const
|
PROGMEM
|
||||||
#endif
|
#endif
|
||||||
char usbDescriptorHidReport[];
|
char usbDescriptorHidReport[];
|
||||||
|
|
||||||
extern
|
extern
|
||||||
#if !(USB_CFG_DESCR_PROPS_STRING_0 & USB_PROP_IS_RAM)
|
#if !(USB_CFG_DESCR_PROPS_STRING_0 & USB_PROP_IS_RAM)
|
||||||
PROGMEM const
|
PROGMEM
|
||||||
#endif
|
#endif
|
||||||
char usbDescriptorString0[];
|
char usbDescriptorString0[];
|
||||||
|
|
||||||
extern
|
extern
|
||||||
#if !(USB_CFG_DESCR_PROPS_STRING_VENDOR & USB_PROP_IS_RAM)
|
#if !(USB_CFG_DESCR_PROPS_STRING_VENDOR & USB_PROP_IS_RAM)
|
||||||
PROGMEM const
|
PROGMEM
|
||||||
#endif
|
#endif
|
||||||
int usbDescriptorStringVendor[];
|
int usbDescriptorStringVendor[];
|
||||||
|
|
||||||
extern
|
extern
|
||||||
#if !(USB_CFG_DESCR_PROPS_STRING_PRODUCT & USB_PROP_IS_RAM)
|
#if !(USB_CFG_DESCR_PROPS_STRING_PRODUCT & USB_PROP_IS_RAM)
|
||||||
PROGMEM const
|
PROGMEM
|
||||||
#endif
|
#endif
|
||||||
int usbDescriptorStringDevice[];
|
int usbDescriptorStringDevice[];
|
||||||
|
|
||||||
extern
|
extern
|
||||||
#if !(USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER & USB_PROP_IS_RAM)
|
#if !(USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER & USB_PROP_IS_RAM)
|
||||||
PROGMEM const
|
PROGMEM
|
||||||
#endif
|
#endif
|
||||||
int usbDescriptorStringSerialNumber[];
|
int usbDescriptorStringSerialNumber[];
|
||||||
|
|
||||||
@ -523,22 +501,22 @@ int usbDescriptorStringSerialNumber[];
|
|||||||
#if !defined __ASSEMBLER__ && (!defined USB_CFG_VENDOR_ID || !defined USB_CFG_DEVICE_ID)
|
#if !defined __ASSEMBLER__ && (!defined USB_CFG_VENDOR_ID || !defined USB_CFG_DEVICE_ID)
|
||||||
#warning "You should define USB_CFG_VENDOR_ID and USB_CFG_DEVICE_ID in usbconfig.h"
|
#warning "You should define USB_CFG_VENDOR_ID and USB_CFG_DEVICE_ID in usbconfig.h"
|
||||||
/* If the user has not defined IDs, we default to obdev's free IDs.
|
/* If the user has not defined IDs, we default to obdev's free IDs.
|
||||||
* See USB-IDs-for-free.txt for details.
|
* See USBID-License.txt for details.
|
||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* make sure we have a VID and PID defined, byte order is lowbyte, highbyte */
|
/* make sure we have a VID and PID defined, byte order is lowbyte, highbyte */
|
||||||
#ifndef USB_CFG_VENDOR_ID
|
#ifndef USB_CFG_VENDOR_ID
|
||||||
# define USB_CFG_VENDOR_ID 0xc0, 0x16 /* = 0x16c0 = 5824 = voti.nl */
|
# define USB_CFG_VENDOR_ID 0xc0, 0x16 /* 5824 in dec, stands for VOTI */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef USB_CFG_DEVICE_ID
|
#ifndef USB_CFG_DEVICE_ID
|
||||||
# if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH
|
# if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH
|
||||||
# define USB_CFG_DEVICE_ID 0xdf, 0x05 /* = 0x5df = 1503, shared PID for HIDs */
|
# define USB_CFG_DEVICE_ID 0xdf, 0x05 /* 1503 in dec, shared PID for HIDs */
|
||||||
# elif USB_CFG_INTERFACE_CLASS == 2
|
# elif USB_CFG_INTERFACE_CLASS == 2
|
||||||
# define USB_CFG_DEVICE_ID 0xe1, 0x05 /* = 0x5e1 = 1505, shared PID for CDC Modems */
|
# define USB_CFG_DEVICE_ID 0xe1, 0x05 /* 1505 in dec, shared PID for CDC Modems */
|
||||||
# else
|
# else
|
||||||
# define USB_CFG_DEVICE_ID 0xdc, 0x05 /* = 0x5dc = 1500, obdev's free PID */
|
# define USB_CFG_DEVICE_ID 0xdc, 0x05 /* 1500 in dec, obdev's free PID */
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -568,10 +546,6 @@ int usbDescriptorStringSerialNumber[];
|
|||||||
#define USB_CFG_EP3_NUMBER 3
|
#define USB_CFG_EP3_NUMBER 3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef USB_CFG_HAVE_INTRIN_ENDPOINT3
|
|
||||||
#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define USB_BUFSIZE 11 /* PID, 8 bytes data, 2 bytes CRC */
|
#define USB_BUFSIZE 11 /* PID, 8 bytes data, 2 bytes CRC */
|
||||||
|
|
||||||
/* ----- Try to find registers and bits responsible for ext interrupt 0 ----- */
|
/* ----- Try to find registers and bits responsible for ext interrupt 0 ----- */
|
||||||
@ -584,15 +558,8 @@ int usbDescriptorStringSerialNumber[];
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef USB_INTR_CFG_SET /* allow user to override our default */
|
#ifndef USB_INTR_CFG_SET /* allow user to override our default */
|
||||||
# if defined(USB_COUNT_SOF) || defined(USB_SOF_HOOK)
|
|
||||||
# define USB_INTR_CFG_SET (1 << ISC01) /* cfg for falling edge */
|
|
||||||
/* If any SOF logic is used, the interrupt must be wired to D- where
|
|
||||||
* we better trigger on falling edge
|
|
||||||
*/
|
|
||||||
# else
|
|
||||||
# define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) /* cfg for rising edge */
|
# define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) /* cfg for rising edge */
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
#ifndef USB_INTR_CFG_CLR /* allow user to override our default */
|
#ifndef USB_INTR_CFG_CLR /* allow user to override our default */
|
||||||
# define USB_INTR_CFG_CLR 0 /* no bits to clear */
|
# define USB_INTR_CFG_CLR 0 /* no bits to clear */
|
||||||
#endif
|
#endif
|
||||||
@ -728,8 +695,7 @@ typedef struct usbRequest{
|
|||||||
#define USBDESCR_HID_REPORT 0x22
|
#define USBDESCR_HID_REPORT 0x22
|
||||||
#define USBDESCR_HID_PHYS 0x23
|
#define USBDESCR_HID_PHYS 0x23
|
||||||
|
|
||||||
//#define USBATTR_BUSPOWER 0x80 // USB 1.1 does not define this value any more
|
#define USBATTR_BUSPOWER 0x80
|
||||||
#define USBATTR_BUSPOWER 0
|
|
||||||
#define USBATTR_SELFPOWER 0x40
|
#define USBATTR_SELFPOWER 0x40
|
||||||
#define USBATTR_REMOTEWAKE 0x20
|
#define USBATTR_REMOTEWAKE 0x20
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
/* Name: usbdrvasm.S
|
/* Name: usbdrvasm.S
|
||||||
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
* Project: AVR USB driver
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2007-06-13
|
* Creation Date: 2007-06-13
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
|
||||||
|
* Revision: $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -14,8 +15,15 @@ general code (preprocessor acrobatics and CRC computation) and then includes
|
|||||||
the file appropriate for the given clock rate.
|
the file appropriate for the given clock rate.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define __SFR_OFFSET 0 /* used by avr-libc's register definitions */
|
#include "iarcompat.h"
|
||||||
#include "usbportability.h"
|
#ifndef __IAR_SYSTEMS_ASM__
|
||||||
|
/* configs for io.h */
|
||||||
|
# define __SFR_OFFSET 0
|
||||||
|
# define _VECTOR(N) __vector_ ## N /* io.h does not define this for asm */
|
||||||
|
# include <avr/io.h> /* for CPU I/O register definitions and vectors */
|
||||||
|
# define macro .macro /* GNU Assembler macro definition */
|
||||||
|
# define endm .endm /* End of GNU Assembler macro definition */
|
||||||
|
#endif /* __IAR_SYSTEMS_ASM__ */
|
||||||
#include "usbdrv.h" /* for common defs */
|
#include "usbdrv.h" /* for common defs */
|
||||||
|
|
||||||
/* register names */
|
/* register names */
|
||||||
@ -25,14 +33,24 @@ the file appropriate for the given clock rate.
|
|||||||
#define cnt r19
|
#define cnt r19
|
||||||
#define x3 r20
|
#define x3 r20
|
||||||
#define x4 r21
|
#define x4 r21
|
||||||
#define x5 r22
|
#define bitcnt r22
|
||||||
#define bitcnt x5
|
|
||||||
#define phase x4
|
#define phase x4
|
||||||
#define leap x4
|
#define leap x4
|
||||||
|
|
||||||
/* Some assembler dependent definitions and declarations: */
|
/* Some assembler dependent definitions and declarations: */
|
||||||
|
|
||||||
#ifdef __IAR_SYSTEMS_ASM__
|
#ifdef __IAR_SYSTEMS_ASM__
|
||||||
|
|
||||||
|
# define nop2 rjmp $+2 /* jump to next instruction */
|
||||||
|
# define XL r26
|
||||||
|
# define XH r27
|
||||||
|
# define YL r28
|
||||||
|
# define YH r29
|
||||||
|
# define ZL r30
|
||||||
|
# define ZH r31
|
||||||
|
# define lo8(x) LOW(x)
|
||||||
|
# define hi8(x) (((x)>>8) & 0xff) /* not HIGH to allow XLINK to make a proper range check */
|
||||||
|
|
||||||
extern usbRxBuf, usbDeviceAddr, usbNewDeviceAddr, usbInputBufOffset
|
extern usbRxBuf, usbDeviceAddr, usbNewDeviceAddr, usbInputBufOffset
|
||||||
extern usbCurrentTok, usbRxLen, usbRxToken, usbTxLen
|
extern usbCurrentTok, usbRxLen, usbRxToken, usbTxLen
|
||||||
extern usbTxBuf, usbTxStatus1, usbTxStatus3
|
extern usbTxBuf, usbTxStatus1, usbTxStatus3
|
||||||
@ -55,12 +73,10 @@ the file appropriate for the given clock rate.
|
|||||||
|
|
||||||
#else /* __IAR_SYSTEMS_ASM__ */
|
#else /* __IAR_SYSTEMS_ASM__ */
|
||||||
|
|
||||||
|
# define nop2 rjmp .+0 /* jump to next instruction */
|
||||||
|
|
||||||
# ifndef USB_INTR_VECTOR /* default to hardware interrupt INT0 */
|
# ifndef USB_INTR_VECTOR /* default to hardware interrupt INT0 */
|
||||||
# ifdef INT0_vect
|
# define USB_INTR_VECTOR SIG_INTERRUPT0
|
||||||
# define USB_INTR_VECTOR INT0_vect // this is the "new" define for the vector
|
|
||||||
# else
|
|
||||||
# define USB_INTR_VECTOR SIG_INTERRUPT0 // this is the "old" vector
|
|
||||||
# endif
|
|
||||||
# endif
|
# endif
|
||||||
.text
|
.text
|
||||||
.global USB_INTR_VECTOR
|
.global USB_INTR_VECTOR
|
||||||
@ -142,93 +158,16 @@ RTMODEL "__rt_version", "3"
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USB_USE_FAST_CRC
|
; extern unsigned usbCrc16(unsigned char *data, unsigned char len);
|
||||||
|
; data: r24/25
|
||||||
; This implementation is faster, but has bigger code size
|
; len: r22
|
||||||
; Thanks to Slawomir Fras (BoskiDialer) for this code!
|
|
||||||
; It implements the following C pseudo-code:
|
|
||||||
; unsigned table(unsigned char x)
|
|
||||||
; {
|
|
||||||
; unsigned value;
|
|
||||||
;
|
|
||||||
; value = (unsigned)x << 6;
|
|
||||||
; value ^= (unsigned)x << 7;
|
|
||||||
; if(parity(x))
|
|
||||||
; value ^= 0xc001;
|
|
||||||
; return value;
|
|
||||||
; }
|
|
||||||
; unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen)
|
|
||||||
; {
|
|
||||||
; unsigned crc = 0xffff;
|
|
||||||
;
|
|
||||||
; while(argLen--)
|
|
||||||
; crc = table(lo8(crc) ^ *argPtr++) ^ hi8(crc);
|
|
||||||
; return ~crc;
|
|
||||||
; }
|
|
||||||
|
|
||||||
; extern unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen);
|
|
||||||
; argPtr r24+25 / r16+r17
|
|
||||||
; argLen r22 / r18
|
|
||||||
; temp variables:
|
; temp variables:
|
||||||
; byte r18 / r22
|
; r18: data byte
|
||||||
; scratch r23
|
; r19: bit counter
|
||||||
; resCrc r24+r25 / r16+r17
|
; r20/21: polynomial
|
||||||
; ptr X / Z
|
; r23: scratch
|
||||||
usbCrc16:
|
; r24/25: crc-sum
|
||||||
mov ptrL, argPtrL
|
; r26/27=X: ptr
|
||||||
mov ptrH, argPtrH
|
|
||||||
ldi resCrcL, 0xFF
|
|
||||||
ldi resCrcH, 0xFF
|
|
||||||
rjmp usbCrc16LoopTest
|
|
||||||
usbCrc16ByteLoop:
|
|
||||||
ld byte, ptr+
|
|
||||||
eor resCrcL, byte ; resCrcL is now 'x' in table()
|
|
||||||
mov byte, resCrcL ; compute parity of 'x'
|
|
||||||
swap byte
|
|
||||||
eor byte, resCrcL
|
|
||||||
mov scratch, byte
|
|
||||||
lsr byte
|
|
||||||
lsr byte
|
|
||||||
eor byte, scratch
|
|
||||||
inc byte
|
|
||||||
lsr byte
|
|
||||||
andi byte, 1 ; byte is now parity(x)
|
|
||||||
mov scratch, resCrcL
|
|
||||||
mov resCrcL, resCrcH
|
|
||||||
eor resCrcL, byte ; low byte of if(parity(x)) value ^= 0xc001;
|
|
||||||
neg byte
|
|
||||||
andi byte, 0xc0
|
|
||||||
mov resCrcH, byte ; high byte of if(parity(x)) value ^= 0xc001;
|
|
||||||
clr byte
|
|
||||||
lsr scratch
|
|
||||||
ror byte
|
|
||||||
eor resCrcH, scratch
|
|
||||||
eor resCrcL, byte
|
|
||||||
lsr scratch
|
|
||||||
ror byte
|
|
||||||
eor resCrcH, scratch
|
|
||||||
eor resCrcL, byte
|
|
||||||
usbCrc16LoopTest:
|
|
||||||
subi argLen, 1
|
|
||||||
brsh usbCrc16ByteLoop
|
|
||||||
com resCrcL
|
|
||||||
com resCrcH
|
|
||||||
ret
|
|
||||||
|
|
||||||
#else /* USB_USE_FAST_CRC */
|
|
||||||
|
|
||||||
; This implementation is slower, but has less code size
|
|
||||||
;
|
|
||||||
; extern unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen);
|
|
||||||
; argPtr r24+25 / r16+r17
|
|
||||||
; argLen r22 / r18
|
|
||||||
; temp variables:
|
|
||||||
; byte r18 / r22
|
|
||||||
; bitCnt r19
|
|
||||||
; poly r20+r21
|
|
||||||
; scratch r23
|
|
||||||
; resCrc r24+r25 / r16+r17
|
|
||||||
; ptr X / Z
|
|
||||||
usbCrc16:
|
usbCrc16:
|
||||||
mov ptrL, argPtrL
|
mov ptrL, argPtrL
|
||||||
mov ptrH, argPtrH
|
mov ptrH, argPtrH
|
||||||
@ -236,30 +175,27 @@ usbCrc16:
|
|||||||
ldi resCrcH, 0
|
ldi resCrcH, 0
|
||||||
ldi polyL, lo8(0xa001)
|
ldi polyL, lo8(0xa001)
|
||||||
ldi polyH, hi8(0xa001)
|
ldi polyH, hi8(0xa001)
|
||||||
com argLen ; argLen = -argLen - 1: modified loop to ensure that carry is set
|
com argLen ; argLen = -argLen - 1
|
||||||
ldi bitCnt, 0 ; loop counter with starnd condition = end condition
|
crcByteLoop:
|
||||||
rjmp usbCrcLoopEntry
|
subi argLen, -1
|
||||||
usbCrcByteLoop:
|
brcc crcReady ; modified loop to ensure that carry is set below
|
||||||
ld byte, ptr+
|
ld byte, ptr+
|
||||||
|
ldi bitCnt, -8 ; strange loop counter to ensure that carry is set where we need it
|
||||||
eor resCrcL, byte
|
eor resCrcL, byte
|
||||||
usbCrcBitLoop:
|
crcBitLoop:
|
||||||
ror resCrcH ; carry is always set here (see brcs jumps to here)
|
ror resCrcH ; carry is always set here
|
||||||
ror resCrcL
|
ror resCrcL
|
||||||
brcs usbCrcNoXor
|
brcs crcNoXor
|
||||||
eor resCrcL, polyL
|
eor resCrcL, polyL
|
||||||
eor resCrcH, polyH
|
eor resCrcH, polyH
|
||||||
usbCrcNoXor:
|
crcNoXor:
|
||||||
subi bitCnt, 224 ; (8 * 224) % 256 = 0; this loop iterates 8 times
|
subi bitCnt, -1
|
||||||
brcs usbCrcBitLoop
|
brcs crcBitLoop
|
||||||
usbCrcLoopEntry:
|
rjmp crcByteLoop
|
||||||
subi argLen, -1
|
crcReady:
|
||||||
brcs usbCrcByteLoop
|
|
||||||
usbCrcReady:
|
|
||||||
ret
|
ret
|
||||||
; Thanks to Reimar Doeffinger for optimizing this CRC routine!
|
; Thanks to Reimar Doeffinger for optimizing this CRC routine!
|
||||||
|
|
||||||
#endif /* USB_USE_FAST_CRC */
|
|
||||||
|
|
||||||
; extern unsigned usbCrc16Append(unsigned char *data, unsigned char len);
|
; extern unsigned usbCrc16Append(unsigned char *data, unsigned char len);
|
||||||
usbCrc16Append:
|
usbCrc16Append:
|
||||||
rcall usbCrc16
|
rcall usbCrc16
|
||||||
@ -360,24 +296,11 @@ usbMFTimeout:
|
|||||||
;----------------------------------------------------------------------------
|
;----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef USB_CFG_CLOCK_KHZ
|
#ifndef USB_CFG_CLOCK_KHZ
|
||||||
# ifdef F_CPU
|
# define USB_CFG_CLOCK_KHZ 12000
|
||||||
# define USB_CFG_CLOCK_KHZ (F_CPU/1000)
|
|
||||||
# else
|
|
||||||
# error "USB_CFG_CLOCK_KHZ not defined in usbconfig.h and no F_CPU set!"
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USB_CFG_CHECK_CRC /* separate dispatcher for CRC type modules */
|
|
||||||
# if USB_CFG_CLOCK_KHZ == 18000
|
|
||||||
# include "usbdrvasm18-crc.inc"
|
|
||||||
# else
|
|
||||||
# error "USB_CFG_CLOCK_KHZ is not one of the supported crc-rates!"
|
|
||||||
# endif
|
|
||||||
#else /* USB_CFG_CHECK_CRC */
|
|
||||||
#if USB_CFG_CLOCK_KHZ == 12000
|
#if USB_CFG_CLOCK_KHZ == 12000
|
||||||
# include "usbdrvasm12.inc"
|
# include "usbdrvasm12.inc"
|
||||||
# elif USB_CFG_CLOCK_KHZ == 12800
|
|
||||||
# include "usbdrvasm128.inc"
|
|
||||||
#elif USB_CFG_CLOCK_KHZ == 15000
|
#elif USB_CFG_CLOCK_KHZ == 15000
|
||||||
# include "usbdrvasm15.inc"
|
# include "usbdrvasm15.inc"
|
||||||
#elif USB_CFG_CLOCK_KHZ == 16000
|
#elif USB_CFG_CLOCK_KHZ == 16000
|
||||||
@ -387,6 +310,5 @@ usbMFTimeout:
|
|||||||
#elif USB_CFG_CLOCK_KHZ == 20000
|
#elif USB_CFG_CLOCK_KHZ == 20000
|
||||||
# include "usbdrvasm20.inc"
|
# include "usbdrvasm20.inc"
|
||||||
#else
|
#else
|
||||||
# error "USB_CFG_CLOCK_KHZ is not one of the supported non-crc-rates!"
|
# error "USB_CFG_CLOCK_KHZ is not one of the supported rates!"
|
||||||
#endif
|
#endif
|
||||||
#endif /* USB_CFG_CHECK_CRC */
|
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
/* Name: usbdrvasm.asm
|
/* Name: usbdrvasm.asm
|
||||||
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
* Project: AVR USB driver
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2006-03-01
|
* Creation Date: 2006-03-01
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
/* Name: usbdrvasm12.inc
|
/* Name: usbdrvasm12.inc
|
||||||
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
* Project: AVR USB driver
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2004-12-29
|
* Creation Date: 2004-12-29
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: usbdrvasm12.inc 483 2008-02-05 15:05:32Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
@ -47,13 +48,10 @@ USB_INTR_VECTOR:
|
|||||||
;----------------------------------------------------------------------------
|
;----------------------------------------------------------------------------
|
||||||
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
|
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
|
||||||
;sync up with J to K edge during sync pattern -- use fastest possible loops
|
;sync up with J to K edge during sync pattern -- use fastest possible loops
|
||||||
;The first part waits at most 1 bit long since we must be in sync pattern.
|
;first part has no timeout because it waits for IDLE or SE1 (== disconnected)
|
||||||
;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
|
|
||||||
;waitForJ, ensure that this prerequisite is met.
|
|
||||||
waitForJ:
|
waitForJ:
|
||||||
inc YL
|
sbis USBIN, USBMINUS ;1 [40] wait for D- == 1
|
||||||
sbis USBIN, USBMINUS
|
rjmp waitForJ ;2
|
||||||
brne waitForJ ; just make sure we have ANY timeout
|
|
||||||
waitForK:
|
waitForK:
|
||||||
;The following code results in a sampling window of 1/4 bit which meets the spec.
|
;The following code results in a sampling window of 1/4 bit which meets the spec.
|
||||||
sbis USBIN, USBMINUS
|
sbis USBIN, USBMINUS
|
||||||
@ -71,9 +69,6 @@ waitForK:
|
|||||||
inc YL
|
inc YL
|
||||||
sts usbSofCount, YL
|
sts usbSofCount, YL
|
||||||
#endif /* USB_COUNT_SOF */
|
#endif /* USB_COUNT_SOF */
|
||||||
#ifdef USB_SOF_HOOK
|
|
||||||
USB_SOF_HOOK
|
|
||||||
#endif
|
|
||||||
rjmp sofError
|
rjmp sofError
|
||||||
foundK:
|
foundK:
|
||||||
;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling]
|
;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling]
|
||||||
@ -268,16 +263,25 @@ macro POP_RETI ; 5 cycles
|
|||||||
; Transmitting data
|
; Transmitting data
|
||||||
;----------------------------------------------------------------------------
|
;----------------------------------------------------------------------------
|
||||||
|
|
||||||
txByteLoop:
|
bitstuff0: ;1 (for branch taken)
|
||||||
txBitloop:
|
eor x1, x4 ;1
|
||||||
stuffN1Delay: ; [03]
|
ldi x2, 0 ;1
|
||||||
ror shift ;[-5] [11] [59]
|
out USBOUT, x1 ;1 <-- out
|
||||||
brcc doExorN1 ;[-4] [60]
|
rjmp didStuff0 ;2 branch back 2 cycles earlier
|
||||||
subi x4, 1 ;[-3]
|
bitstuff1: ;1 (for branch taken)
|
||||||
brne commonN1 ;[-2]
|
eor x1, x4 ;1
|
||||||
lsl shift ;[-1] compensate ror after rjmp stuffDelay
|
rjmp didStuff1 ;2 we know that C is clear, jump back to do OUT and ror 0 into x2
|
||||||
nop ;[00] stuffing consists of just waiting 8 cycles
|
bitstuff2: ;1 (for branch taken)
|
||||||
rjmp stuffN1Delay ;[01] after ror, C bit is reliably clear
|
eor x1, x4 ;1
|
||||||
|
rjmp didStuff2 ;2 jump back 4 cycles earlier and do out and ror 0 into x2
|
||||||
|
bitstuff3: ;1 (for branch taken)
|
||||||
|
eor x1, x4 ;1
|
||||||
|
rjmp didStuff3 ;2 jump back earlier and ror 0 into x2
|
||||||
|
bitstuff4: ;1 (for branch taken)
|
||||||
|
eor x1, x4 ;1
|
||||||
|
ldi x2, 0 ;1
|
||||||
|
out USBOUT, x1 ;1 <-- out
|
||||||
|
rjmp didStuff4 ;2 jump back 2 cycles earlier
|
||||||
|
|
||||||
sendNakAndReti: ;0 [-19] 19 cycles until SOP
|
sendNakAndReti: ;0 [-19] 19 cycles until SOP
|
||||||
ldi x3, USBPID_NAK ;1 [-18]
|
ldi x3, USBPID_NAK ;1 [-18]
|
||||||
@ -302,91 +306,122 @@ usbSendX3: ;0 [-16]
|
|||||||
;usbSend:
|
;usbSend:
|
||||||
;pointer to data in 'Y'
|
;pointer to data in 'Y'
|
||||||
;number of bytes in 'cnt' -- including sync byte
|
;number of bytes in 'cnt' -- including sync byte
|
||||||
;uses: x1...x2, x4, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x4 = bitstuff cnt]
|
;uses: x1...x4, shift, cnt, Y
|
||||||
;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction)
|
;Numbers in brackets are time since first bit of sync pattern is sent
|
||||||
usbSendAndReti:
|
usbSendAndReti: ;0 [-13] timing: 13 cycles until SOP
|
||||||
in x2, USBDDR ;[-12] 12 cycles until SOP
|
in x2, USBDDR ;1 [-12]
|
||||||
ori x2, USBMASK ;[-11]
|
ori x2, USBMASK ;1 [-11]
|
||||||
sbi USBOUT, USBMINUS ;[-10] prepare idle state; D+ and D- must have been 0 (no pullups)
|
sbi USBOUT, USBMINUS;2 [-9] prepare idle state; D+ and D- must have been 0 (no pullups)
|
||||||
out USBDDR, x2 ;[-8] <--- acquire bus
|
in x1, USBOUT ;1 [-8] port mirror for tx loop
|
||||||
in x1, USBOUT ;[-7] port mirror for tx loop
|
out USBDDR, x2 ;1 [-7] <- acquire bus
|
||||||
ldi shift, 0x40 ;[-6] sync byte is first byte sent (we enter loop after ror)
|
; need not init x2 (bitstuff history) because sync starts with 0
|
||||||
ldi x2, USBMASK ;[-5]
|
push x4 ;2 [-5]
|
||||||
push x4 ;[-4]
|
ldi x4, USBMASK ;1 [-4] exor mask
|
||||||
doExorN1:
|
ldi shift, 0x80 ;1 [-3] sync byte is first byte sent
|
||||||
eor x1, x2 ;[-2] [06] [62]
|
txLoop: ; [62]
|
||||||
ldi x4, 6 ;[-1] [07] [63]
|
sbrs shift, 0 ;1 [-2] [62]
|
||||||
commonN1:
|
eor x1, x4 ;1 [-1] [63]
|
||||||
stuffN2Delay:
|
out USBOUT, x1 ;1 [0] <-- out bit 0
|
||||||
out USBOUT, x1 ;[00] [08] [64] <--- set bit
|
ror shift ;1 [1]
|
||||||
ror shift ;[01]
|
ror x2 ;1 [2]
|
||||||
brcc doExorN2 ;[02]
|
didStuff0:
|
||||||
subi x4, 1 ;[03]
|
cpi x2, 0xfc ;1 [3]
|
||||||
brne commonN2 ;[04]
|
brsh bitstuff0 ;1 [4]
|
||||||
lsl shift ;[05] compensate ror after rjmp stuffDelay
|
sbrs shift, 0 ;1 [5]
|
||||||
rjmp stuffN2Delay ;[06] after ror, C bit is reliably clear
|
eor x1, x4 ;1 [6]
|
||||||
doExorN2:
|
ror shift ;1 [7]
|
||||||
eor x1, x2 ;[04] [12]
|
didStuff1:
|
||||||
ldi x4, 6 ;[05] [13]
|
out USBOUT, x1 ;1 [8] <-- out bit 1
|
||||||
commonN2:
|
ror x2 ;1 [9]
|
||||||
nop ;[06] [14]
|
cpi x2, 0xfc ;1 [10]
|
||||||
subi cnt, 171 ;[07] [15] trick: (3 * 171) & 0xff = 1
|
brsh bitstuff1 ;1 [11]
|
||||||
out USBOUT, x1 ;[08] [16] <--- set bit
|
sbrs shift, 0 ;1 [12]
|
||||||
brcs txBitloop ;[09] [25] [41]
|
eor x1, x4 ;1 [13]
|
||||||
|
ror shift ;1 [14]
|
||||||
stuff6Delay:
|
didStuff2:
|
||||||
ror shift ;[42] [50]
|
ror x2 ;1 [15]
|
||||||
brcc doExor6 ;[43]
|
out USBOUT, x1 ;1 [16] <-- out bit 2
|
||||||
subi x4, 1 ;[44]
|
cpi x2, 0xfc ;1 [17]
|
||||||
brne common6 ;[45]
|
brsh bitstuff2 ;1 [18]
|
||||||
lsl shift ;[46] compensate ror after rjmp stuffDelay
|
sbrs shift, 0 ;1 [19]
|
||||||
nop ;[47] stuffing consists of just waiting 8 cycles
|
eor x1, x4 ;1 [20]
|
||||||
rjmp stuff6Delay ;[48] after ror, C bit is reliably clear
|
ror shift ;1 [21]
|
||||||
doExor6:
|
didStuff3:
|
||||||
eor x1, x2 ;[45] [53]
|
ror x2 ;1 [22]
|
||||||
ldi x4, 6 ;[46]
|
cpi x2, 0xfc ;1 [23]
|
||||||
common6:
|
out USBOUT, x1 ;1 [24] <-- out bit 3
|
||||||
stuff7Delay:
|
brsh bitstuff3 ;1 [25]
|
||||||
ror shift ;[47] [55]
|
nop2 ;2 [27]
|
||||||
out USBOUT, x1 ;[48] <--- set bit
|
ld x3, y+ ;2 [29]
|
||||||
brcc doExor7 ;[49]
|
sbrs shift, 0 ;1 [30]
|
||||||
subi x4, 1 ;[50]
|
eor x1, x4 ;1 [31]
|
||||||
brne common7 ;[51]
|
out USBOUT, x1 ;1 [32] <-- out bit 4
|
||||||
lsl shift ;[52] compensate ror after rjmp stuffDelay
|
ror shift ;1 [33]
|
||||||
rjmp stuff7Delay ;[53] after ror, C bit is reliably clear
|
ror x2 ;1 [34]
|
||||||
doExor7:
|
didStuff4:
|
||||||
eor x1, x2 ;[51] [59]
|
cpi x2, 0xfc ;1 [35]
|
||||||
ldi x4, 6 ;[52]
|
brsh bitstuff4 ;1 [36]
|
||||||
common7:
|
sbrs shift, 0 ;1 [37]
|
||||||
ld shift, y+ ;[53]
|
eor x1, x4 ;1 [38]
|
||||||
tst cnt ;[55]
|
ror shift ;1 [39]
|
||||||
out USBOUT, x1 ;[56] <--- set bit
|
didStuff5:
|
||||||
brne txByteLoop ;[57]
|
out USBOUT, x1 ;1 [40] <-- out bit 5
|
||||||
|
ror x2 ;1 [41]
|
||||||
|
cpi x2, 0xfc ;1 [42]
|
||||||
|
brsh bitstuff5 ;1 [43]
|
||||||
|
sbrs shift, 0 ;1 [44]
|
||||||
|
eor x1, x4 ;1 [45]
|
||||||
|
ror shift ;1 [46]
|
||||||
|
didStuff6:
|
||||||
|
ror x2 ;1 [47]
|
||||||
|
out USBOUT, x1 ;1 [48] <-- out bit 6
|
||||||
|
cpi x2, 0xfc ;1 [49]
|
||||||
|
brsh bitstuff6 ;1 [50]
|
||||||
|
sbrs shift, 0 ;1 [51]
|
||||||
|
eor x1, x4 ;1 [52]
|
||||||
|
ror shift ;1 [53]
|
||||||
|
didStuff7:
|
||||||
|
ror x2 ;1 [54]
|
||||||
|
cpi x2, 0xfc ;1 [55]
|
||||||
|
out USBOUT, x1 ;1 [56] <-- out bit 7
|
||||||
|
brsh bitstuff7 ;1 [57]
|
||||||
|
mov shift, x3 ;1 [58]
|
||||||
|
dec cnt ;1 [59]
|
||||||
|
brne txLoop ;1/2 [60/61]
|
||||||
;make SE0:
|
;make SE0:
|
||||||
cbr x1, USBMASK ;[58] prepare SE0 [spec says EOP may be 15 to 18 cycles]
|
cbr x1, USBMASK ;1 [61] prepare SE0 [spec says EOP may be 15 to 18 cycles]
|
||||||
lds x2, usbNewDeviceAddr;[59]
|
pop x4 ;2 [63]
|
||||||
lsl x2 ;[61] we compare with left shifted address
|
;brackets are cycles from start of SE0 now
|
||||||
subi YL, 2 + 20 ;[62] Only assign address on data packets, not ACK/NAK in x3
|
out USBOUT, x1 ;1 [0] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle
|
||||||
sbci YH, 0 ;[63]
|
|
||||||
out USBOUT, x1 ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle
|
|
||||||
;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:
|
;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:
|
||||||
;set address only after data packet was sent, not after handshake
|
;set address only after data packet was sent, not after handshake
|
||||||
breq skipAddrAssign ;[01]
|
lds x2, usbNewDeviceAddr;2 [2]
|
||||||
|
lsl x2; ;1 [3] we compare with left shifted address
|
||||||
|
subi YL, 20 + 2 ;1 [4] Only assign address on data packets, not ACK/NAK in x3
|
||||||
|
sbci YH, 0 ;1 [5]
|
||||||
|
breq skipAddrAssign ;2 [7]
|
||||||
sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer
|
sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer
|
||||||
skipAddrAssign:
|
skipAddrAssign:
|
||||||
;end of usbDeviceAddress transfer
|
;end of usbDeviceAddress transfer
|
||||||
ldi x2, 1<<USB_INTR_PENDING_BIT;[03] int0 occurred during TX -- clear pending flag
|
ldi x2, 1<<USB_INTR_PENDING_BIT;1 [8] int0 occurred during TX -- clear pending flag
|
||||||
USB_STORE_PENDING(x2) ;[04]
|
USB_STORE_PENDING(x2) ;1 [9]
|
||||||
ori x1, USBIDLE ;[05]
|
ori x1, USBIDLE ;1 [10]
|
||||||
in x2, USBDDR ;[06]
|
in x2, USBDDR ;1 [11]
|
||||||
cbr x2, USBMASK ;[07] set both pins to input
|
cbr x2, USBMASK ;1 [12] set both pins to input
|
||||||
mov x3, x1 ;[08]
|
mov x3, x1 ;1 [13]
|
||||||
cbr x3, USBMASK ;[09] configure no pullup on both pins
|
cbr x3, USBMASK ;1 [14] configure no pullup on both pins
|
||||||
pop x4 ;[10]
|
out USBOUT, x1 ;1 [15] <-- out J (idle) -- end of SE0 (EOP signal)
|
||||||
nop2 ;[12]
|
out USBDDR, x2 ;1 [16] <-- release bus now
|
||||||
nop2 ;[14]
|
out USBOUT, x3 ;1 [17] <-- ensure no pull-up resistors are active
|
||||||
out USBOUT, x1 ;[16] <-- out J (idle) -- end of SE0 (EOP signal)
|
|
||||||
out USBDDR, x2 ;[17] <-- release bus now
|
|
||||||
out USBOUT, x3 ;[18] <-- ensure no pull-up resistors are active
|
|
||||||
rjmp doReturn
|
rjmp doReturn
|
||||||
|
|
||||||
|
bitstuff5: ;1 (for branch taken)
|
||||||
|
eor x1, x4 ;1
|
||||||
|
rjmp didStuff5 ;2 same trick as in bitstuff1...
|
||||||
|
bitstuff6: ;1 (for branch taken)
|
||||||
|
eor x1, x4 ;1
|
||||||
|
rjmp didStuff6 ;2 same trick as above...
|
||||||
|
bitstuff7: ;1 (for branch taken)
|
||||||
|
eor x1, x4 ;1
|
||||||
|
rjmp didStuff7 ;2 same trick as above...
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: usbdrvasm128.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
@ -30,9 +31,8 @@ limitations:
|
|||||||
They typical range is 14.5 MHz and most AVRs can actually reach this rate.
|
They typical range is 14.5 MHz and most AVRs can actually reach this rate.
|
||||||
(2) Writing EEPROM and Flash may be unreliable (short data lifetime) since
|
(2) Writing EEPROM and Flash may be unreliable (short data lifetime) since
|
||||||
the write procedure is timed from the RC oscillator.
|
the write procedure is timed from the RC oscillator.
|
||||||
(3) End Of Packet detection (SE0) should be in bit 1, bit it is only checked
|
(3) End Of Packet detection is between bit 0 and bit 1 where the EOP condition
|
||||||
if bits 0 and 1 both read as 0 on D- and D+ read as 0 in the middle. This may
|
may not be reliable when a hub is used. It should be in bit 1.
|
||||||
cause problems with old hubs which delay SE0 by up to one cycle.
|
|
||||||
(4) Code size is much larger than that of the other modules.
|
(4) Code size is much larger than that of the other modules.
|
||||||
|
|
||||||
Since almost all of this code is timing critical, don't change unless you
|
Since almost all of this code is timing critical, don't change unless you
|
||||||
@ -217,10 +217,8 @@ unstuff0s:
|
|||||||
ifioclr USBIN, USBMINUS ;[00]
|
ifioclr USBIN, USBMINUS ;[00]
|
||||||
ifioset USBIN, USBPLUS ;[01]
|
ifioset USBIN, USBPLUS ;[01]
|
||||||
rjmp bit0IsClr ;[02] executed if first expr false or second true
|
rjmp bit0IsClr ;[02] executed if first expr false or second true
|
||||||
se0AndStore: ; executed only if both bits 0
|
jumpToSe0AndStore:
|
||||||
st y+, x1 ;[15/17] cycles after start of byte
|
rjmp se0AndStore ;[03] executed only if both bits 0
|
||||||
rjmp se0 ;[17/19]
|
|
||||||
|
|
||||||
bit0IsClr:
|
bit0IsClr:
|
||||||
ifrset phase, USBMINUS ;[04] check phase only if D- changed
|
ifrset phase, USBMINUS ;[04] check phase only if D- changed
|
||||||
lpm ;[05]
|
lpm ;[05]
|
||||||
@ -230,7 +228,7 @@ bit1AfterClr:
|
|||||||
andi phase, USBMASK ;[08]
|
andi phase, USBMASK ;[08]
|
||||||
ifioset USBIN, USBMINUS ;[09] <--- sample 1
|
ifioset USBIN, USBMINUS ;[09] <--- sample 1
|
||||||
rjmp bit1IsSet ;[10]
|
rjmp bit1IsSet ;[10]
|
||||||
breq se0AndStore ;[11] if D- was 0 in bits 0 AND 1 and D+ was 0 in between, we have SE0
|
breq jumpToSe0AndStore ;[11]
|
||||||
andi shift, ~(7 << 1) ;[12]
|
andi shift, ~(7 << 1) ;[12]
|
||||||
in phase, USBIN ;[13] <- phase
|
in phase, USBIN ;[13] <- phase
|
||||||
breq unstuff1c ;[14]
|
breq unstuff1c ;[14]
|
||||||
@ -357,6 +355,10 @@ unstuff7c:
|
|||||||
nop ;[59]
|
nop ;[59]
|
||||||
rjmp bit7IsSet ;[60]
|
rjmp bit7IsSet ;[60]
|
||||||
|
|
||||||
|
se0AndStore:
|
||||||
|
st y+, x1 ;[15/17] cycles after start of byte
|
||||||
|
rjmp se0 ;[17/19]
|
||||||
|
|
||||||
bit7IsClr:
|
bit7IsClr:
|
||||||
ifrset phase, USBMINUS ;[62] check phase only if D- changed
|
ifrset phase, USBMINUS ;[62] check phase only if D- changed
|
||||||
lpm ;[63]
|
lpm ;[63]
|
||||||
@ -389,24 +391,25 @@ bit0IsSet:
|
|||||||
in phase, USBIN ;[06] <- phase (one cycle too late)
|
in phase, USBIN ;[06] <- phase (one cycle too late)
|
||||||
ori shift, 1 << 0 ;[07]
|
ori shift, 1 << 0 ;[07]
|
||||||
bit1AfterSet:
|
bit1AfterSet:
|
||||||
andi shift, ~(7 << 1) ;[08] compensated by "ori shift, 1<<1" if bit1IsClr
|
andi phase, USBMASK ;[08]
|
||||||
ifioclr USBIN, USBMINUS ;[09] <--- sample 1
|
ifioclr USBIN, USBMINUS ;[09] <--- sample 1
|
||||||
rjmp bit1IsClr ;[10]
|
rjmp bit1IsClr ;[10]
|
||||||
breq unstuff1s ;[11]
|
andi shift, ~(7 << 1) ;[11]
|
||||||
nop2 ;[12] do not check for SE0 if bit 0 was 1
|
breq unstuff1s ;[12]
|
||||||
in phase, USBIN ;[14] <- phase (one cycle too late)
|
in phase, USBIN ;[13] <- phase
|
||||||
|
nop ;[14]
|
||||||
rjmp bit2AfterSet ;[15]
|
rjmp bit2AfterSet ;[15]
|
||||||
unstuff1s:
|
unstuff1s:
|
||||||
in phase, USBIN ;[13] <- phase
|
in phase, USBIN ;[14] <- phase (one cycle too late)
|
||||||
andi fix, ~(1 << 1) ;[14]
|
andi fix, ~(1 << 1) ;[15]
|
||||||
lpm ;[07]
|
nop2 ;[08]
|
||||||
nop2 ;[10]
|
nop2 ;[10]
|
||||||
bit1IsClr:
|
bit1IsClr:
|
||||||
ifrset phase, USBMINUS ;[12] check phase only if D- changed
|
ifrset phase, USBMINUS ;[12] check phase only if D- changed
|
||||||
lpm ;[13]
|
lpm ;[13]
|
||||||
in phase, USBIN ;[14] <- phase (one cycle too late)
|
in phase, USBIN ;[14] <- phase (one cycle too late)
|
||||||
ori shift, 1 << 1 ;[15]
|
breq se0AndStore ;[15] if we come from unstuff1s, Z bit is never set
|
||||||
nop ;[16]
|
ori shift, 1 << 1 ;[16]
|
||||||
bit2AfterClr:
|
bit2AfterClr:
|
||||||
ifioset USBIN, USBMINUS ;[17] <--- sample 2
|
ifioset USBIN, USBMINUS ;[17] <--- sample 2
|
||||||
rjmp bit2IsSet ;[18]
|
rjmp bit2IsSet ;[18]
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
/* Name: usbdrvasm15.inc
|
/* Name: usbdrvasm15.inc
|
||||||
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
* Project: AVR USB driver
|
||||||
* Author: contributed by V. Bosch
|
* Author: contributed by V. Bosch
|
||||||
* Creation Date: 2007-08-06
|
* Creation Date: 2007-08-06
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
|
||||||
|
* Revision: $Id: usbdrvasm15.inc 607 2008-05-13 15:57:28Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
@ -42,13 +43,11 @@ USB_INTR_VECTOR:
|
|||||||
;
|
;
|
||||||
; sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
|
; sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
|
||||||
; sync up with J to K edge during sync pattern -- use fastest possible loops
|
; sync up with J to K edge during sync pattern -- use fastest possible loops
|
||||||
;The first part waits at most 1 bit long since we must be in sync pattern.
|
; first part has no timeout because it waits for IDLE or SE1 (== disconnected)
|
||||||
;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
|
;-------------------------------------------------------------------------------
|
||||||
;waitForJ, ensure that this prerequisite is met.
|
waitForJ: ;-
|
||||||
waitForJ:
|
sbis USBIN, USBMINUS ;1 <-- sample: wait for D- == 1
|
||||||
inc YL
|
rjmp waitForJ ;2
|
||||||
sbis USBIN, USBMINUS
|
|
||||||
brne waitForJ ; just make sure we have ANY timeout
|
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; The following code results in a sampling window of < 1/4 bit
|
; The following code results in a sampling window of < 1/4 bit
|
||||||
; which meets the spec.
|
; which meets the spec.
|
||||||
@ -71,9 +70,6 @@ waitForK: ;-
|
|||||||
inc YL
|
inc YL
|
||||||
sts usbSofCount, YL
|
sts usbSofCount, YL
|
||||||
#endif /* USB_COUNT_SOF */
|
#endif /* USB_COUNT_SOF */
|
||||||
#ifdef USB_SOF_HOOK
|
|
||||||
USB_SOF_HOOK
|
|
||||||
#endif
|
|
||||||
rjmp sofError
|
rjmp sofError
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
; {3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for
|
; {3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
/* Name: usbdrvasm16.inc
|
/* Name: usbdrvasm16.inc
|
||||||
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
* Project: AVR USB driver
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2007-06-15
|
* Creation Date: 2007-06-15
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
|
||||||
|
* Revision: $Id: usbdrvasm16.inc 607 2008-05-13 15:57:28Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
@ -40,13 +41,10 @@ USB_INTR_VECTOR:
|
|||||||
;----------------------------------------------------------------------------
|
;----------------------------------------------------------------------------
|
||||||
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
|
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
|
||||||
;sync up with J to K edge during sync pattern -- use fastest possible loops
|
;sync up with J to K edge during sync pattern -- use fastest possible loops
|
||||||
;The first part waits at most 1 bit long since we must be in sync pattern.
|
;first part has no timeout because it waits for IDLE or SE1 (== disconnected)
|
||||||
;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
|
|
||||||
;waitForJ, ensure that this prerequisite is met.
|
|
||||||
waitForJ:
|
waitForJ:
|
||||||
inc YL
|
sbis USBIN, USBMINUS ;[-18] wait for D- == 1
|
||||||
sbis USBIN, USBMINUS
|
rjmp waitForJ
|
||||||
brne waitForJ ; just make sure we have ANY timeout
|
|
||||||
waitForK:
|
waitForK:
|
||||||
;The following code results in a sampling window of < 1/4 bit which meets the spec.
|
;The following code results in a sampling window of < 1/4 bit which meets the spec.
|
||||||
sbis USBIN, USBMINUS ;[-15]
|
sbis USBIN, USBMINUS ;[-15]
|
||||||
@ -66,9 +64,6 @@ waitForK:
|
|||||||
inc YL
|
inc YL
|
||||||
sts usbSofCount, YL
|
sts usbSofCount, YL
|
||||||
#endif /* USB_COUNT_SOF */
|
#endif /* USB_COUNT_SOF */
|
||||||
#ifdef USB_SOF_HOOK
|
|
||||||
USB_SOF_HOOK
|
|
||||||
#endif
|
|
||||||
rjmp sofError
|
rjmp sofError
|
||||||
foundK: ;[-12]
|
foundK: ;[-12]
|
||||||
;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling]
|
;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling]
|
||||||
@ -116,15 +111,12 @@ haveTwoBitsK:
|
|||||||
; Receiver loop (numbers in brackets are cycles within byte after instr)
|
; Receiver loop (numbers in brackets are cycles within byte after instr)
|
||||||
;----------------------------------------------------------------------------
|
;----------------------------------------------------------------------------
|
||||||
|
|
||||||
; duration of unstuffing code should be 10.66666667 cycles. We adjust "leap"
|
|
||||||
; accordingly to approximate this value in the long run.
|
|
||||||
|
|
||||||
unstuff6:
|
unstuff6:
|
||||||
andi x2, USBMASK ;[03]
|
andi x2, USBMASK ;[03]
|
||||||
ori x3, 1<<6 ;[04] will not be shifted any more
|
ori x3, 1<<6 ;[04] will not be shifted any more
|
||||||
andi shift, ~0x80;[05]
|
andi shift, ~0x80;[05]
|
||||||
mov x1, x2 ;[06] sampled bit 7 is actually re-sampled bit 6
|
mov x1, x2 ;[06] sampled bit 7 is actually re-sampled bit 6
|
||||||
subi leap, -1 ;[07] total duration = 11 bits -> subtract 1/3
|
subi leap, 3 ;[07] since this is a short (10 cycle) bit, enforce leap bit
|
||||||
rjmp didUnstuff6 ;[08]
|
rjmp didUnstuff6 ;[08]
|
||||||
|
|
||||||
unstuff7:
|
unstuff7:
|
||||||
@ -132,7 +124,7 @@ unstuff7:
|
|||||||
in x2, USBIN ;[00] [10] re-sample bit 7
|
in x2, USBIN ;[00] [10] re-sample bit 7
|
||||||
andi x2, USBMASK ;[01]
|
andi x2, USBMASK ;[01]
|
||||||
andi shift, ~0x80;[02]
|
andi shift, ~0x80;[02]
|
||||||
subi leap, 2 ;[03] total duration = 10 bits -> add 1/3
|
subi leap, 3 ;[03] since this is a short (10 cycle) bit, enforce leap bit
|
||||||
rjmp didUnstuff7 ;[04]
|
rjmp didUnstuff7 ;[04]
|
||||||
|
|
||||||
unstuffEven:
|
unstuffEven:
|
||||||
@ -141,8 +133,8 @@ unstuffEven:
|
|||||||
andi shift, ~0x80;[01]
|
andi shift, ~0x80;[01]
|
||||||
andi x1, USBMASK ;[02]
|
andi x1, USBMASK ;[02]
|
||||||
breq se0 ;[03]
|
breq se0 ;[03]
|
||||||
subi leap, -1 ;[04] total duration = 11 bits -> subtract 1/3
|
subi leap, 3 ;[04] since this is a short (10 cycle) bit, enforce leap bit
|
||||||
nop2 ;[05]
|
nop ;[05]
|
||||||
rjmp didUnstuffE ;[06]
|
rjmp didUnstuffE ;[06]
|
||||||
|
|
||||||
unstuffOdd:
|
unstuffOdd:
|
||||||
@ -151,8 +143,8 @@ unstuffOdd:
|
|||||||
andi shift, ~0x80;[01]
|
andi shift, ~0x80;[01]
|
||||||
andi x2, USBMASK ;[02]
|
andi x2, USBMASK ;[02]
|
||||||
breq se0 ;[03]
|
breq se0 ;[03]
|
||||||
subi leap, -1 ;[04] total duration = 11 bits -> subtract 1/3
|
subi leap, 3 ;[04] since this is a short (10 cycle) bit, enforce leap bit
|
||||||
nop2 ;[05]
|
nop ;[05]
|
||||||
rjmp didUnstuffO ;[06]
|
rjmp didUnstuffO ;[06]
|
||||||
|
|
||||||
rxByteLoop:
|
rxByteLoop:
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
/* Name: usbdrvasm165.inc
|
/* Name: usbdrvasm165.inc
|
||||||
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
* Project: AVR USB driver
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2007-04-22
|
* Creation Date: 2007-04-22
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
|
||||||
|
* Revision: $Id: usbdrvasm165.inc 607 2008-05-13 15:57:28Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
@ -45,13 +46,10 @@ USB_INTR_VECTOR:
|
|||||||
;----------------------------------------------------------------------------
|
;----------------------------------------------------------------------------
|
||||||
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
|
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
|
||||||
;sync up with J to K edge during sync pattern -- use fastest possible loops
|
;sync up with J to K edge during sync pattern -- use fastest possible loops
|
||||||
;The first part waits at most 1 bit long since we must be in sync pattern.
|
;first part has no timeout because it waits for IDLE or SE1 (== disconnected)
|
||||||
;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
|
|
||||||
;waitForJ, ensure that this prerequisite is met.
|
|
||||||
waitForJ:
|
waitForJ:
|
||||||
inc YL
|
sbis USBIN, USBMINUS ;[-18] wait for D- == 1
|
||||||
sbis USBIN, USBMINUS
|
rjmp waitForJ
|
||||||
brne waitForJ ; just make sure we have ANY timeout
|
|
||||||
waitForK:
|
waitForK:
|
||||||
;The following code results in a sampling window of < 1/4 bit which meets the spec.
|
;The following code results in a sampling window of < 1/4 bit which meets the spec.
|
||||||
sbis USBIN, USBMINUS ;[-15]
|
sbis USBIN, USBMINUS ;[-15]
|
||||||
@ -71,9 +69,6 @@ waitForK:
|
|||||||
inc YL
|
inc YL
|
||||||
sts usbSofCount, YL
|
sts usbSofCount, YL
|
||||||
#endif /* USB_COUNT_SOF */
|
#endif /* USB_COUNT_SOF */
|
||||||
#ifdef USB_SOF_HOOK
|
|
||||||
USB_SOF_HOOK
|
|
||||||
#endif
|
|
||||||
rjmp sofError
|
rjmp sofError
|
||||||
foundK: ;[-12]
|
foundK: ;[-12]
|
||||||
;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling]
|
;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling]
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2008 by Lukas Schrittwieser and OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2008 by Lukas Schrittwieser and OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* Revision: $Id: usbdrvasm18-crc.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
/* Name: usbdrvasm20.inc
|
/* Name: usbdrvasm20.inc
|
||||||
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
* Project: AVR USB driver
|
||||||
* Author: Jeroen Benschop
|
* Author: Jeroen Benschop
|
||||||
* Based on usbdrvasm16.inc from Christian Starkjohann
|
* Based on usbdrvasm16.inc from Christian Starkjohann
|
||||||
* Creation Date: 2008-03-05
|
* Creation Date: 2008-03-05
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2008 by Jeroen Benschop and OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2008 by Jeroen Benschop and OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
|
||||||
|
* Revision: $Id: usbdrvasm20.inc 607 2008-05-13 15:57:28Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
@ -56,13 +57,10 @@ USB_INTR_VECTOR:
|
|||||||
;----------------------------------------------------------------------------
|
;----------------------------------------------------------------------------
|
||||||
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
|
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
|
||||||
;sync up with J to K edge during sync pattern -- use fastest possible loops
|
;sync up with J to K edge during sync pattern -- use fastest possible loops
|
||||||
;The first part waits at most 1 bit long since we must be in sync pattern.
|
;first part has no timeout because it waits for IDLE or SE1 (== disconnected)
|
||||||
;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
|
|
||||||
;waitForJ, ensure that this prerequisite is met.
|
|
||||||
waitForJ:
|
waitForJ:
|
||||||
inc YL
|
sbis USBIN, USBMINUS ;[-21] wait for D- == 1
|
||||||
sbis USBIN, USBMINUS
|
rjmp waitForJ
|
||||||
brne waitForJ ; just make sure we have ANY timeout
|
|
||||||
waitForK:
|
waitForK:
|
||||||
;The following code results in a sampling window of < 1/4 bit which meets the spec.
|
;The following code results in a sampling window of < 1/4 bit which meets the spec.
|
||||||
sbis USBIN, USBMINUS ;[-19]
|
sbis USBIN, USBMINUS ;[-19]
|
||||||
@ -88,9 +86,6 @@ waitForK:
|
|||||||
inc YL
|
inc YL
|
||||||
sts usbSofCount, YL
|
sts usbSofCount, YL
|
||||||
#endif /* USB_COUNT_SOF */
|
#endif /* USB_COUNT_SOF */
|
||||||
#ifdef USB_SOF_HOOK
|
|
||||||
USB_SOF_HOOK
|
|
||||||
#endif
|
|
||||||
rjmp sofError
|
rjmp sofError
|
||||||
foundK: ;[-16]
|
foundK: ;[-16]
|
||||||
;{3, 5} after falling D- edge, average delay: 4 cycles
|
;{3, 5} after falling D- edge, average delay: 4 cycles
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: usbportability.h 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -124,11 +125,7 @@ static inline void sei(void)
|
|||||||
# include <avr/pgmspace.h>
|
# include <avr/pgmspace.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USB_CFG_DRIVER_FLASH_PAGE
|
|
||||||
# define USB_READ_FLASH(addr) pgm_read_byte_far(((long)USB_CFG_DRIVER_FLASH_PAGE << 16) | (long)(addr))
|
|
||||||
#else
|
|
||||||
#define USB_READ_FLASH(addr) pgm_read_byte(addr)
|
#define USB_READ_FLASH(addr) pgm_read_byte(addr)
|
||||||
#endif
|
|
||||||
|
|
||||||
#define macro .macro
|
#define macro .macro
|
||||||
#define endm .endm
|
#define endm .endm
|
||||||
|
|||||||
@ -19,56 +19,27 @@
|
|||||||
DEBUG = 1
|
DEBUG = 1
|
||||||
TTY = /dev/tty.PL2303-00002126
|
TTY = /dev/tty.PL2303-00002126
|
||||||
DEVICE = atmega644
|
DEVICE = atmega644
|
||||||
F_CPU = 20000000
|
F_CPU = 20000000 # in Hz
|
||||||
TARGET = main
|
TARGET = main
|
||||||
AVRDUDE = avrdude -c usbasp -p $(DEVICE)
|
AVRDUDE = avrdude -c usbasp -p $(DEVICE)
|
||||||
SIZE = avr-size
|
SIZE = avr-size
|
||||||
BOOT_LOADER = 1
|
|
||||||
BOOT_COMPRESS = rle
|
|
||||||
BOOT_ROM01 = ../../roms/qd16boot_ver01.smc
|
|
||||||
BOOT_ROM02 = ../../roms/qd16boot_ver02.smc
|
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(DEBUG),1)
|
ifeq ($(DEBUG),1)
|
||||||
BOOT_DEBUG = debug
|
LDFLAGS = -Wl,-u,vfprintf -lprintf_flt
|
||||||
LDFLAGS =-Wl,-u,vfprintf
|
|
||||||
CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0
|
CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0
|
||||||
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o \
|
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o \
|
||||||
main.o usb_bulk.o uart.o fifo.o sram.o debug.o \
|
main.o usb_bulk.o uart.o fifo.o sram.o crc.o debug.o \
|
||||||
dump.o timer.o watchdog.o loader.o info.o shared_memory.o crc.o \
|
dump.o timer.o watchdog.o rle.c loader.o info.o shared_memory.o \
|
||||||
system.o pwm.o util.o shell.o irq.o command.o
|
irq.o command.o testing.o
|
||||||
else
|
else
|
||||||
BOOT_DEBUG = nodebug
|
LDFLAGS = -Wl,-u
|
||||||
LDFLAGS =
|
|
||||||
CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0 -DNO_DEBUG -DNO_INFO
|
CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0 -DNO_DEBUG -DNO_INFO
|
||||||
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o usb_bulk.o \
|
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o usb_bulk.o \
|
||||||
sram.o crc.o debug.o dump.o loader.o \
|
uart.o fifo.o sram.o crc.o debug.o dump.o timer.o watchdog.o rle.c loader.o \
|
||||||
system.o util.o info.o shared_memory.o command.o irq.o \
|
info.o shared_memory.o command.o irq.o
|
||||||
pwm.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(BOOT_LOADER), 1)
|
|
||||||
BOOT_ROM = $(BOOT_ROM01)
|
|
||||||
else
|
|
||||||
BOOT_ROM = $(BOOT_ROM02)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(BOOT_COMPRESS), rle)
|
|
||||||
BOOT_CONVERTER = python ../../scripts/conv_rle.py
|
|
||||||
CFLAGS += -DBOOT_COMPRESS_RLE
|
|
||||||
OBJECTS += rle.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(BOOT_COMPRESS), zip)
|
|
||||||
BOOT_CONVERTER = python ../../scripts/conv_zip.py
|
|
||||||
CFLAGS += -DBOOT_COMPRESS_ZIP
|
|
||||||
OBJECTS += neginf/neginf.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(BOOT_COMPRESS), fastlz)
|
|
||||||
BOOT_CONVERTER = python ../../scripts/conv_fastlz.py
|
|
||||||
CFLAGS += -DBOOT_COMPRESS_FASTLZ
|
|
||||||
OBJECTS += fastlz.o
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(F_CPU) $(CFLAGS) -mmcu=$(DEVICE)
|
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(F_CPU) $(CFLAGS) -mmcu=$(DEVICE)
|
||||||
@ -85,6 +56,7 @@ all: hex
|
|||||||
help:
|
help:
|
||||||
@echo "This Makefile has no default rule. Use one of the following:"
|
@echo "This Makefile has no default rule. Use one of the following:"
|
||||||
@echo "make hex ....... to build main.hex"
|
@echo "make hex ....... to build main.hex"
|
||||||
|
@echo "make program ... to flash fuses and firmware"
|
||||||
@echo "make fuse ...... to flash the fuses"
|
@echo "make fuse ...... to flash the fuses"
|
||||||
@echo "make flash ..... to flash the firmware (use this on metaboard)"
|
@echo "make flash ..... to flash the firmware (use this on metaboard)"
|
||||||
@echo "make clean ..... to delete objects and hex file"
|
@echo "make clean ..... to delete objects and hex file"
|
||||||
@ -93,6 +65,8 @@ hex: main.hex
|
|||||||
@echo "$(TARGET) compiled for: $(DEVICE)"
|
@echo "$(TARGET) compiled for: $(DEVICE)"
|
||||||
@./checksize $(TARGET).elf
|
@./checksize $(TARGET).elf
|
||||||
|
|
||||||
|
program: flash fuse
|
||||||
|
|
||||||
# rule for programming fuse bits:
|
# rule for programming fuse bits:
|
||||||
fuse:
|
fuse:
|
||||||
@[ "$(FUSE_H)" != "" -a "$(FUSE_L)" != "" ] || \
|
@[ "$(FUSE_H)" != "" -a "$(FUSE_L)" != "" ] || \
|
||||||
@ -102,11 +76,6 @@ fuse:
|
|||||||
flash: main.hex
|
flash: main.hex
|
||||||
$(AVRDUDE) -U flash:w:main.hex:i
|
$(AVRDUDE) -U flash:w:main.hex:i
|
||||||
|
|
||||||
convert-boot-rom:
|
|
||||||
$(BOOT_CONVERTER) $(BOOT_ROM)
|
|
||||||
|
|
||||||
release: main.hex
|
|
||||||
cp -v main.hex ../../files/firmware/firmware-loader0$(BOOT_LOADER)-$(BOOT_COMPRESS)-$(BOOT_DEBUG)-$$(date +%Y%m%d).hex
|
|
||||||
|
|
||||||
.c.o:
|
.c.o:
|
||||||
$(COMPILE) -c $< -o $@
|
$(COMPILE) -c $< -o $@
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
* =====================================================================================
|
* =====================================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -27,173 +28,38 @@
|
|||||||
#include "sram.h"
|
#include "sram.h"
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
#include "usbdrv.h"
|
|
||||||
|
|
||||||
#if defined(BOOT_COMPRESS_RLE)
|
extern uint32_t req_bank_size;
|
||||||
#include "rle.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(BOOT_COMPRESS_ZIP)
|
|
||||||
#include "neginf/neginf.h"
|
|
||||||
#include "inflate.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(BOOT_COMPRESS_FASTLZ)
|
|
||||||
#include "fastlz.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "loader.h"
|
|
||||||
#include "system.h"
|
|
||||||
|
|
||||||
|
|
||||||
extern usb_transaction_t usb_trans;
|
void send_reset()
|
||||||
extern system_t my_system;
|
|
||||||
|
|
||||||
extern const char *_rom[];
|
|
||||||
extern const char _rom01[];
|
|
||||||
extern const int _rom_size[];
|
|
||||||
|
|
||||||
void usb_connect()
|
|
||||||
{
|
{
|
||||||
uint8_t i = 0;
|
info_P(PSTR("Reset SNES\n"));
|
||||||
info_P(PSTR("USB init\n"));
|
|
||||||
usbDeviceDisconnect(); /* enforce re-enumeration, do this while */
|
|
||||||
cli();
|
cli();
|
||||||
info_P(PSTR("USB disconnect\n"));
|
snes_reset_on();
|
||||||
i = 10;
|
snes_reset_lo();
|
||||||
while (--i) { /* fake USB disconnect for > 250 ms */
|
_delay_ms(2);
|
||||||
_delay_ms(50);
|
snes_reset_hi();
|
||||||
}
|
snes_reset_off();
|
||||||
led_on();
|
sei();
|
||||||
usbDeviceConnect();
|
|
||||||
info_P(PSTR("USB connect\n"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void send_irq()
|
||||||
|
|
||||||
void boot_startup_rom(uint16_t init_delay)
|
|
||||||
{
|
{
|
||||||
uint8_t i;
|
snes_irq_on();
|
||||||
|
|
||||||
#if defined(BOOT_COMPRESS_RLE)
|
|
||||||
uint32_t addr = 0x000000;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(BOOT_COMPRESS_ZIP)
|
|
||||||
uint8_t c;
|
|
||||||
uint16_t j;
|
|
||||||
PGM_VOID_P p_addr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
info_P(PSTR("Fetch Loader: %s from AVR PROGMEM\n"), LOADER_NAME);
|
|
||||||
|
|
||||||
system_set_bus_avr();
|
|
||||||
// snes_irq_lo();
|
|
||||||
// system_snes_irq_off();
|
|
||||||
system_set_rom_lorom();
|
|
||||||
|
|
||||||
// info_P(PSTR("Activate AVR bus\n"));
|
|
||||||
// avr_bus_active();
|
|
||||||
// info_P(PSTR("IRQ off\n"));
|
|
||||||
// snes_irq_lo();
|
|
||||||
// snes_irq_off();
|
|
||||||
// snes_lorom();
|
|
||||||
|
|
||||||
info_P(PSTR("Unpack Loader with using method: %s\n"), LOADER_COMPRESS);
|
|
||||||
#if defined(BOOT_COMPRESS_RLE)
|
|
||||||
for (i = 0; i < ROM_BUFFER_CNT; i++) {
|
|
||||||
addr += rle_decode(_rom[i], _rom_size[i], addr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(BOOT_COMPRESS_ZIP)
|
|
||||||
//inflate_init();
|
|
||||||
neginf_init(0);
|
|
||||||
for (i=0; i<ROM_BUFFER_CNT; i++){
|
|
||||||
p_addr = _rom[i];
|
|
||||||
info_P(PSTR("idx=%i addr=%lx %s\n"), i, p_addr);
|
|
||||||
for (j=0; j<_rom_size[i]; j++){
|
|
||||||
c = pgm_read_byte((PGM_VOID_P)p_addr++);
|
|
||||||
neginf_process_byte(c);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(BOOT_COMPRESS_FASTLZ)
|
|
||||||
uint32_t rlen = _rom_size[0]+ _rom_size[1];
|
|
||||||
fastlz_decompress2(_rom[0], _rom[0], rlen);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
info_P(PSTR("\n"));
|
|
||||||
|
|
||||||
|
|
||||||
#if DO_CRC_CHECK_LOADER
|
|
||||||
dump_memory(0x010000 - 0x100, 0x010000);
|
|
||||||
uint16_t crc;
|
|
||||||
crc = crc_check_bulk_memory((uint32_t) 0x000000, 0x010000, 0x010000);
|
|
||||||
info(PSTR("crc=%x\n"), crc);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// snes_irq_lo();
|
|
||||||
// snes_irq_off();
|
|
||||||
// snes_hirom();
|
|
||||||
// snes_wr_disable();
|
|
||||||
|
|
||||||
// system_set_bus_snes();
|
|
||||||
// system_set_rom_hirom();
|
|
||||||
// system_set_wr_disable();
|
|
||||||
// system_snes_irq_off();
|
|
||||||
|
|
||||||
snes_irq_lo();
|
snes_irq_lo();
|
||||||
system_snes_irq_off();
|
_delay_us(20);
|
||||||
system_set_rom_hirom();
|
snes_irq_hi();
|
||||||
system_set_wr_disable();
|
snes_irq_off();
|
||||||
system_set_bus_snes();
|
|
||||||
|
|
||||||
|
|
||||||
system_send_snes_reset();
|
|
||||||
info_P(PSTR("Move Loader to wram"));
|
|
||||||
for (i = 0; i < 30; i++) {
|
|
||||||
_delay_ms(20);
|
|
||||||
info_P(PSTR("."));
|
|
||||||
}
|
|
||||||
info_P(PSTR("\n"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void banner()
|
void set_rom_mode()
|
||||||
{
|
{
|
||||||
uint8_t i;
|
if (req_bank_size == 0x8000) {
|
||||||
for (i = 0; i < 40; i++)
|
snes_lorom();
|
||||||
info_P(PSTR("\n"));
|
info_P(PSTR("Set SNES lowrom \n"));
|
||||||
info_P(PSTR
|
} else {
|
||||||
(" ________ .__ __ ________ ____ ________\n"));
|
snes_hirom();
|
||||||
info_P(PSTR
|
info_P(PSTR("Set SNES hirom \n"));
|
||||||
(" \\_____ \\ __ __|__| ____ | | __\\______ \\ _______ _/_ |/ _____/\n"));
|
|
||||||
info_P(PSTR
|
|
||||||
(" / / \\ \\| | \\ |/ ___\\| |/ / | | \\_/ __ \\ \\/ /| / __ \\ \n"));
|
|
||||||
info_P(PSTR
|
|
||||||
(" / \\_/. \\ | / \\ \\___| < | ` \\ ___/\\ / | \\ |__\\ \\ \n"));
|
|
||||||
info_P(PSTR
|
|
||||||
(" \\_____\\ \\_/____/|__|\\___ >__|_ \\/_______ /\\___ >\\_/ |___|\\_____ / \n"));
|
|
||||||
info_P(PSTR
|
|
||||||
(" \\__> \\/ \\/ \\/ \\/ \\/ \n"));
|
|
||||||
info_P(PSTR("\n"));
|
|
||||||
info_P(PSTR(" www.optixx.org\n"));
|
|
||||||
info_P(PSTR("\n"));
|
|
||||||
info_P(PSTR("Hardware Version: %s Software Version: %s Build Date: %s \n"), HW_VERSION, SW_VERSION, __DATE__ );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void transaction_status()
|
|
||||||
{
|
|
||||||
info_P(PSTR("\nAddr 0x%06lx\n"), usb_trans.req_addr);
|
|
||||||
info_P(PSTR("Bank 0x%02x\n"), usb_trans.req_bank);
|
|
||||||
info_P(PSTR("Banksize 0x%06lx\n"), usb_trans.req_bank_size);
|
|
||||||
info_P(PSTR("Bankcount 0x%02x\n"), usb_trans.req_bank_cnt);
|
|
||||||
info_P(PSTR("Status 0x%02x\n"), usb_trans.req_state);
|
|
||||||
info_P(PSTR("Percent %02i\n"), usb_trans.req_percent);
|
|
||||||
info_P(PSTR("TX buffer %02i\n"), usb_trans.tx_remaining);
|
|
||||||
info_P(PSTR("RX buffer %02i\n"), usb_trans.rx_remaining);
|
|
||||||
info_P(PSTR("Syncerr %02i\n"), usb_trans.sync_errors);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,10 +22,8 @@
|
|||||||
#ifndef __COMMAND_H__
|
#ifndef __COMMAND_H__
|
||||||
#define __COMMAND_H__
|
#define __COMMAND_H__
|
||||||
|
|
||||||
void usb_connect();
|
void send_reset();
|
||||||
void boot_startup_rom(uint16_t init_delay);
|
void send_irq();
|
||||||
void banner();
|
void set_rom_mode();
|
||||||
void transaction_status();
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -42,17 +42,9 @@
|
|||||||
#define USB_MAX_TRANS 0xff
|
#define USB_MAX_TRANS 0xff
|
||||||
#define USB_CRC_CHECK 0x01
|
#define USB_CRC_CHECK 0x01
|
||||||
|
|
||||||
#define TRANSFER_BUFFER_SIZE 0x000
|
#define TRANSFER_BUFFER_SIZE 0x200
|
||||||
#define FORMAT_BUFFER_LEN 0x080
|
#define FORMAT_BUFFER_LEN 0x0FF
|
||||||
#define RECEIVE_BUF_LEN 0x030
|
|
||||||
#define HW_VERSION "2.6"
|
#define HW_VERSION "2.6"
|
||||||
#define SW_VERSION "1.2"
|
#define SW_VERSION "1.0"
|
||||||
|
|
||||||
#define DO_CRC_CHECK_LOADER 0
|
|
||||||
#define DO_CRC_CHECK 1
|
|
||||||
#define DO_SHM_SCRATCHPAD 0
|
|
||||||
#define DO_SHM 0
|
|
||||||
#define DO_TIMER 1
|
|
||||||
#define DO_SHELL 1
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -65,23 +65,18 @@ uint16_t do_crc_update(uint16_t crc, uint8_t * data, uint16_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t top_addr,
|
uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t top_addr, uint32_t bank_size)
|
||||||
uint32_t bank_size)
|
|
||||||
{
|
{
|
||||||
uint16_t crc = 0;
|
uint16_t crc = 0;
|
||||||
uint32_t addr = 0;
|
uint32_t addr = 0;
|
||||||
uint8_t req_bank = 0;
|
uint8_t req_bank = 0;
|
||||||
sram_bulk_read_start(bottom_addr);
|
sram_bulk_read_start(bottom_addr);
|
||||||
debug_P(DEBUG_CRC,
|
debug_P(DEBUG_CRC, PSTR("crc_check_bulk_memory: bottom_addr=0x%08lx top_addr=0x%08lx\n"),
|
||||||
PSTR
|
|
||||||
("crc_check_bulk_memory: bottom_addr=0x%08lx top_addr=0x%08lx\n"),
|
|
||||||
bottom_addr,top_addr);
|
bottom_addr,top_addr);
|
||||||
|
|
||||||
for (addr = bottom_addr; addr < top_addr; addr++) {
|
for (addr = bottom_addr; addr < top_addr; addr++) {
|
||||||
if (addr && ((addr % bank_size) == 0)) {
|
if (addr && addr % bank_size == 0) {
|
||||||
debug_P(DEBUG_CRC,
|
debug_P(DEBUG_CRC, PSTR("crc_check_bulk_memory: bank=0x%02x addr=0x%08lx crc=0x%04x\n"),
|
||||||
PSTR
|
|
||||||
("crc_check_bulk_memory: bank=0x%02x addr=0x%08lx crc=0x%04x\n"),
|
|
||||||
req_bank,addr,crc);
|
req_bank,addr,crc);
|
||||||
req_bank++;
|
req_bank++;
|
||||||
crc = 0;
|
crc = 0;
|
||||||
@ -90,9 +85,7 @@ uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t top_addr,
|
|||||||
sram_bulk_read_next();
|
sram_bulk_read_next();
|
||||||
}
|
}
|
||||||
if (addr % 0x8000 == 0)
|
if (addr % 0x8000 == 0)
|
||||||
debug_P(DEBUG_CRC,
|
debug_P(DEBUG_CRC, PSTR("crc_check_bulk_memory: bank=0x%02x addr=0x%08lx crc=0x%04x\n"),
|
||||||
PSTR
|
|
||||||
("crc_check_bulk_memory: bank=0x%02x addr=0x%08lx crc=0x%04x\n"),
|
|
||||||
req_bank,addr,crc);
|
req_bank,addr,crc);
|
||||||
sram_bulk_read_end();
|
sram_bulk_read_end();
|
||||||
return crc;
|
return crc;
|
||||||
@ -101,13 +94,11 @@ uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t top_addr,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t crc_check_memory_range(uint32_t start_addr, uint32_t size,
|
uint16_t crc_check_memory_range(uint32_t start_addr, uint32_t size,uint8_t *buffer)
|
||||||
uint8_t * buffer)
|
|
||||||
{
|
{
|
||||||
uint16_t crc = 0;
|
uint16_t crc = 0;
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
for (addr = start_addr; addr < start_addr + size;
|
for (addr = start_addr; addr < start_addr + size; addr += TRANSFER_BUFFER_SIZE) {
|
||||||
addr += TRANSFER_BUFFER_SIZE) {
|
|
||||||
sram_bulk_copy_into_buffer(addr, buffer, TRANSFER_BUFFER_SIZE);
|
sram_bulk_copy_into_buffer(addr, buffer, TRANSFER_BUFFER_SIZE);
|
||||||
crc = do_crc_update(crc, buffer, TRANSFER_BUFFER_SIZE);
|
crc = do_crc_update(crc, buffer, TRANSFER_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,9 +29,7 @@
|
|||||||
uint16_t crc_xmodem_update(uint16_t crc, uint8_t data);
|
uint16_t crc_xmodem_update(uint16_t crc, uint8_t data);
|
||||||
uint16_t do_crc(uint8_t * data,uint16_t size);
|
uint16_t do_crc(uint8_t * data,uint16_t size);
|
||||||
uint16_t do_crc_update(uint16_t crc,uint8_t * data,uint16_t size);
|
uint16_t do_crc_update(uint16_t crc,uint8_t * data,uint16_t size);
|
||||||
uint16_t crc_check_memory_range(uint32_t start_addr, uint32_t size,
|
uint16_t crc_check_memory_range(uint32_t start_addr, uint32_t size,uint8_t *buffer);
|
||||||
uint8_t * buffer);
|
uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t bank_size,uint32_t top_addr);
|
||||||
uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t bank_size,
|
|
||||||
uint32_t top_addr);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -32,8 +32,7 @@ extern int debug_level; /* the higher, the more messages... */
|
|||||||
|
|
||||||
#if defined(NO_DEBUG) && defined(__GNUC__)
|
#if defined(NO_DEBUG) && defined(__GNUC__)
|
||||||
#else
|
#else
|
||||||
void debug(int level, char *format, ...)
|
void debug(int level, char* format, ...) {
|
||||||
{
|
|
||||||
#ifdef NO_DEBUG
|
#ifdef NO_DEBUG
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -53,17 +52,16 @@ uint8_t buffer_debug[FORMAT_BUFFER_LEN];
|
|||||||
|
|
||||||
#if defined(NO_DEBUG) && defined(__GNUC__)
|
#if defined(NO_DEBUG) && defined(__GNUC__)
|
||||||
#else
|
#else
|
||||||
void debug_P(int level, PGM_P format, ...)
|
void debug_P(int level, PGM_P format, ...) {
|
||||||
{
|
|
||||||
#ifdef NO_DEBUG
|
#ifdef NO_DEBUG
|
||||||
|
|
||||||
#else
|
#else
|
||||||
va_list args;
|
va_list args;
|
||||||
if (!(debug_level & level))
|
if (!(debug_level & level))
|
||||||
return;
|
return;
|
||||||
strlcpy_P((char *) buffer_debug, format, FORMAT_BUFFER_LEN);
|
strlcpy_P(buffer_debug,format,FORMAT_BUFFER_LEN);
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
vprintf((char *) buffer_debug, args);
|
vprintf(buffer_debug, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,30 +29,27 @@
|
|||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
#if defined(NO_DEBUG) && defined(__GNUC__)
|
#if defined(NO_DEBUG) && defined(__GNUC__)
|
||||||
/*
|
/* gcc's cpp has extensions; it allows for macros with a variable number of
|
||||||
* gcc's cpp has extensions; it allows for macros with a variable number of arguments. We use this extension here to preprocess pmesg away.
|
arguments. We use this extension here to preprocess pmesg away. */
|
||||||
*/
|
|
||||||
#define debug(level, format, args...) ((void)0)
|
#define debug(level, format, args...) ((void)0)
|
||||||
#else
|
#else
|
||||||
void debug(int level, char *format, ...);
|
void debug(int level, char *format, ...);
|
||||||
/*
|
/* print a message, if it is considered significant enough.
|
||||||
* print a message, if it is considered significant enough. Adapted from [K&R2], p. 174
|
Adapted from [K&R2], p. 174 */
|
||||||
*/
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(NO_DEBUG) && defined(__GNUC__)
|
#if defined(NO_DEBUG) && defined(__GNUC__)
|
||||||
/*
|
/* gcc's cpp has extensions; it allows for macros with a variable number of
|
||||||
* gcc's cpp has extensions; it allows for macros with a variable number of arguments. We use this extension here to preprocess pmesg away.
|
arguments. We use this extension here to preprocess pmesg away. */
|
||||||
*/
|
|
||||||
#define debug_P(level, format, args...) ((void)0)
|
#define debug_P(level, format, args...) ((void)0)
|
||||||
#else
|
#else
|
||||||
void debug_P(int level, PGM_P format, ...);
|
void debug_P(int level, PGM_P format, ...);
|
||||||
/*
|
/* print a message, if it is considered significant enough.
|
||||||
* print a message, if it is considered significant enough. Adapted from [K&R2], p. 174
|
Adapted from [K&R2], p. 174 */
|
||||||
*/
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* DEBUG_H */
|
#endif /* DEBUG_H */
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,6 @@
|
|||||||
#include "info.h"
|
#include "info.h"
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "sram.h"
|
#include "sram.h"
|
||||||
#include "dump.h"
|
|
||||||
|
|
||||||
|
|
||||||
extern FILE uart_stdout;
|
extern FILE uart_stdout;
|
||||||
|
|||||||
@ -31,3 +31,4 @@ void dump_memory(uint32_t bottom_addr, uint32_t top_addr);
|
|||||||
void dump_packet(uint32_t addr,uint32_t len,uint8_t *packet);
|
void dump_packet(uint32_t addr,uint32_t len,uint8_t *packet);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -1,197 +0,0 @@
|
|||||||
|
|
||||||
#if defined(__GNUC__) && (__GNUC__ > 2)
|
|
||||||
#define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
|
|
||||||
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
|
|
||||||
#else
|
|
||||||
#define FASTLZ_EXPECT_CONDITIONAL(c) (c)
|
|
||||||
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (c)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Use inlined functions for supported systems.
|
|
||||||
*/
|
|
||||||
#if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C)
|
|
||||||
#define FASTLZ_INLINE inline
|
|
||||||
#elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__)
|
|
||||||
#define FASTLZ_INLINE __inline
|
|
||||||
#else
|
|
||||||
#define FASTLZ_INLINE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef unsigned char flzuint8;
|
|
||||||
typedef unsigned short flzuint16;
|
|
||||||
typedef unsigned int flzuint32;
|
|
||||||
|
|
||||||
/* prototypes */
|
|
||||||
int fastlz_decompress(const void* input, int length, void* output);
|
|
||||||
|
|
||||||
#define MAX_DISTANCE 256
|
|
||||||
|
|
||||||
|
|
||||||
#include <avr/pgmspace.h> /* required by usbdrv.h */
|
|
||||||
#include <util/delay.h> /* for _delay_ms() */
|
|
||||||
#include <avr/interrupt.h> /* for sei() */
|
|
||||||
|
|
||||||
#include "sram.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "info.h"
|
|
||||||
#include "ringbuffer.h"
|
|
||||||
|
|
||||||
//#define log2(NUM) printf("%i op=%i(%x) ip=%i(%x) ref=%i(%x) dist=%i buf->end=%i len=%i ctrl=%i ofs=%i(%i) limit=%i\n",NUM, output_index,output[output_index], input_index,input[input_index],ref_index,input[ref_index],output_index - ref_index,ref_buffer_ptr->end, len, ctrl, ofs, ofs>>6,input_index < ip_limit);
|
|
||||||
|
|
||||||
#define log2(NUM) info_P(PSTR("%i op=%i ip=%i ref=%i dist=%i buf->end=%i len=%i ctrl=%i ofs=%i(%i) limit=%i\n"),NUM, output_index, input_index,ref_index,output_index - ref_index,ref_buffer_ptr->end, len, ctrl, ofs, ofs>>6,input_index < ip_limit);
|
|
||||||
|
|
||||||
#define OUTPUT_INC(B) do { \
|
|
||||||
__b = B;\
|
|
||||||
sram_bulk_write(__b);\
|
|
||||||
sram_bulk_write_next();\
|
|
||||||
bufferWrite(ref_buffer_ptr, __b);\
|
|
||||||
output_index++;\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define OUTPUT_INC_FROM_REFINC() do { \
|
|
||||||
__dist = (output_index-ref_index); \
|
|
||||||
__c = buffer_get(ref_buffer_ptr, __dist); \
|
|
||||||
sram_bulk_write(__c);\
|
|
||||||
sram_bulk_write_next();\
|
|
||||||
output_index++;\
|
|
||||||
bufferWrite(ref_buffer_ptr, __c);\
|
|
||||||
ref_index++;\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
#define FROM_REF(OUT) do { \
|
|
||||||
flzuint16 __dist = (output_index-ref_index+1); \
|
|
||||||
OUT = buffer_get(ref_buffer_ptr, __dist); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define OUTBYTE(OUT) do { \
|
|
||||||
sram_bulk_write(OUT);\
|
|
||||||
sram_bulk_write_next();\
|
|
||||||
output_index++;\
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define INBYTE(IN) do { \
|
|
||||||
cli();\
|
|
||||||
IN = pgm_read_byte((PGM_VOID_P)input_index++); \
|
|
||||||
sei();\
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define INPUT_INC(IN) do { \
|
|
||||||
cli();\
|
|
||||||
if (input_index<32768) { \
|
|
||||||
IN = pgm_read_byte((PGM_VOID_P)input_index++); \
|
|
||||||
} else { \
|
|
||||||
IN = pgm_read_byte((PGM_VOID_P)input_index-32768); \
|
|
||||||
input_index++; \
|
|
||||||
}\
|
|
||||||
sei();\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
ring_buffer_typedef(unsigned char, byte_buffer);
|
|
||||||
|
|
||||||
int fastlz_decompress2(unsigned char* input1, unsigned char* input2, int length)
|
|
||||||
{
|
|
||||||
flzuint32 input_index = 0;
|
|
||||||
flzuint32 ip_limit = length;
|
|
||||||
flzuint32 output_index = 0;
|
|
||||||
flzuint32 ref_index = 0;
|
|
||||||
//flzuint32 ctrl = (input[input_index++]) & 31;
|
|
||||||
flzuint32 ctrl;
|
|
||||||
INPUT_INC(ctrl);
|
|
||||||
ctrl = ctrl & 31;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int loop = 1;
|
|
||||||
|
|
||||||
byte_buffer ref_buffer;
|
|
||||||
buffer_init(ref_buffer, MAX_DISTANCE, unsigned char);
|
|
||||||
byte_buffer* ref_buffer_ptr;
|
|
||||||
ref_buffer_ptr = &ref_buffer;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
flzuint8 __b;
|
|
||||||
flzuint16 __dist;
|
|
||||||
flzuint8 __c;
|
|
||||||
flzuint8 tmp;
|
|
||||||
|
|
||||||
ref_index = output_index;
|
|
||||||
flzuint32 len = ctrl >> 5;
|
|
||||||
flzuint32 ofs = (ctrl & 31) << 6;
|
|
||||||
//log2(1)
|
|
||||||
if(ctrl >= 32)
|
|
||||||
{
|
|
||||||
len--;
|
|
||||||
ref_index -= ofs;
|
|
||||||
if (len == 7-1){
|
|
||||||
INPUT_INC(tmp);
|
|
||||||
len += tmp;
|
|
||||||
//len += input[input_index++];
|
|
||||||
}
|
|
||||||
INPUT_INC(tmp);
|
|
||||||
ref_index -= tmp;
|
|
||||||
//ref_index -= input[input_index++];
|
|
||||||
|
|
||||||
//log2(1)
|
|
||||||
|
|
||||||
if(FASTLZ_EXPECT_CONDITIONAL( input_index < ip_limit))
|
|
||||||
INPUT_INC(ctrl);
|
|
||||||
//ctrl = input[input_index++];
|
|
||||||
else
|
|
||||||
loop = 0;
|
|
||||||
|
|
||||||
//log2(1)
|
|
||||||
|
|
||||||
if(ref_index == output_index)
|
|
||||||
{
|
|
||||||
//log2(2)
|
|
||||||
//flzuint8 b = output[ref_index-1];
|
|
||||||
flzuint8 b;
|
|
||||||
FROM_REF(b);
|
|
||||||
|
|
||||||
|
|
||||||
OUTPUT_INC(b);
|
|
||||||
OUTPUT_INC(b);
|
|
||||||
OUTPUT_INC(b);
|
|
||||||
for(; len; --len)
|
|
||||||
OUTPUT_INC(b);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//log2(3)
|
|
||||||
ref_index--;
|
|
||||||
OUTPUT_INC_FROM_REFINC();
|
|
||||||
OUTPUT_INC_FROM_REFINC();
|
|
||||||
OUTPUT_INC_FROM_REFINC();
|
|
||||||
for(; len; --len)
|
|
||||||
OUTPUT_INC_FROM_REFINC();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ctrl++;
|
|
||||||
//log2(4)
|
|
||||||
INPUT_INC(tmp);
|
|
||||||
OUTPUT_INC(tmp);
|
|
||||||
//OUTPUT_INC(input[input_index++]);
|
|
||||||
for(--ctrl; ctrl; ctrl--){
|
|
||||||
//log2(5)
|
|
||||||
INPUT_INC(tmp);
|
|
||||||
OUTPUT_INC(tmp);
|
|
||||||
//OUTPUT_INC(input[input_index++]);
|
|
||||||
}
|
|
||||||
|
|
||||||
loop = FASTLZ_EXPECT_CONDITIONAL(input_index < ip_limit);
|
|
||||||
if (loop){
|
|
||||||
INPUT_INC(ctrl);
|
|
||||||
//ctrl = input[input_index++];
|
|
||||||
}
|
|
||||||
//log2(6)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(FASTLZ_EXPECT_CONDITIONAL(loop));
|
|
||||||
buffer_destroy(ref_buffer_ptr);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
#ifndef FASTLZ_H
|
|
||||||
#define FASTLZ_H
|
|
||||||
|
|
||||||
#define FASTLZ_VERSION 0x000100
|
|
||||||
|
|
||||||
#define FASTLZ_VERSION_MAJOR 0
|
|
||||||
#define FASTLZ_VERSION_MINOR 0
|
|
||||||
#define FASTLZ_VERSION_REVISION 0
|
|
||||||
|
|
||||||
#define FASTLZ_VERSION_STRING "0.1.0"
|
|
||||||
|
|
||||||
int fastlz_decompress2(const void* input1, const void* input2, int length);
|
|
||||||
|
|
||||||
#endif /* FASTLZ_H */
|
|
||||||
@ -37,8 +37,7 @@ extern FILE uart_stdout;
|
|||||||
#define info(format, args...) ((void)0)
|
#define info(format, args...) ((void)0)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
void info(char *format, ...)
|
void info(char* format, ...) {
|
||||||
{
|
|
||||||
#ifdef NO_INFO
|
#ifdef NO_INFO
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -60,16 +59,16 @@ uint8_t buffer_info[FORMAT_BUFFER_LEN];
|
|||||||
#define info(format, args...) ((void)0)
|
#define info(format, args...) ((void)0)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
void info_P(PGM_P format, ...)
|
void info_P(PGM_P format, ...) {
|
||||||
{
|
|
||||||
#ifdef NO_INFO
|
#ifdef NO_INFO
|
||||||
|
|
||||||
#else
|
#else
|
||||||
strlcpy_P((char *) buffer_info, format, FORMAT_BUFFER_LEN);
|
strlcpy_P(buffer_info,format,FORMAT_BUFFER_LEN);
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
vprintf((char *) buffer_info, args);
|
vprintf(buffer_info, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -29,28 +29,24 @@
|
|||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
#if defined(NO_INFO) && defined(__GNUC__)
|
#if defined(NO_INFO) && defined(__GNUC__)
|
||||||
/*
|
/* gcc's cpp has extensions; it allows for macros with a variable number of
|
||||||
* gcc's cpp has extensions; it allows for macros with a variable number of arguments. We use this extension here to preprocess pmesg away.
|
arguments. We use this extension here to preprocess pmesg away. */
|
||||||
*/
|
|
||||||
#define info(format, args...) ((void)0)
|
#define info(format, args...) ((void)0)
|
||||||
#else
|
#else
|
||||||
void info(char *format, ...);
|
void info(char *format, ...);
|
||||||
/*
|
/* print a message, if it is considered significant enough.
|
||||||
* print a message, if it is considered significant enough. Adapted from [K&R2], p. 174
|
Adapted from [K&R2], p. 174 */
|
||||||
*/
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(NO_INFO) && defined(__GNUC__)
|
#if defined(NO_INFO) && defined(__GNUC__)
|
||||||
/*
|
/* gcc's cpp has extensions; it allows for macros with a variable number of
|
||||||
* gcc's cpp has extensions; it allows for macros with a variable number of arguments. We use this extension here to preprocess pmesg away.
|
arguments. We use this extension here to preprocess pmesg away. */
|
||||||
*/
|
|
||||||
#define info_P(format, args...) ((void)0)
|
#define info_P(format, args...) ((void)0)
|
||||||
#else
|
#else
|
||||||
void info_P(PGM_P format, ...);
|
void info_P(PGM_P format, ...);
|
||||||
/*
|
/* print a message, if it is considered significant enough.
|
||||||
* print a message, if it is considered significant enough. Adapted from [K&R2], p. 174
|
Adapted from [K&R2], p. 174 */
|
||||||
*/
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -23,49 +23,45 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <avr/io.h>
|
||||||
#include <avr/interrupt.h> /* for sei() */
|
#include <avr/interrupt.h> /* for sei() */
|
||||||
#include <avr/wdt.h>
|
#include <avr/wdt.h>
|
||||||
|
|
||||||
|
|
||||||
#include "usbdrv.h"
|
#include "usbdrv.h"
|
||||||
#include "oddebug.h" /* This is also an example for using debug macros */
|
#include "oddebug.h" /* This is also an example for using debug
|
||||||
|
* macros */
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
#include "sram.h"
|
#include "sram.h"
|
||||||
#include "system.h"
|
|
||||||
|
|
||||||
extern system_t my_system;
|
|
||||||
|
|
||||||
void (*jump_to_app) (void) = 0x0000;
|
void (*jump_to_app) (void) = 0x0000;
|
||||||
|
|
||||||
void irq_init()
|
void irq_init(){
|
||||||
{
|
|
||||||
cli();
|
cli();
|
||||||
PCMSK3 |=(1<<PCINT27);
|
PCMSK3 |=(1<<PCINT27);
|
||||||
PCICR |= (1<<PCIE3);
|
PCICR |= (1<<PCIE3);
|
||||||
sei();
|
sei();
|
||||||
my_system.reset_irq = RESET_IRQ_ON;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void irq_stop()
|
void irq_stop(){
|
||||||
{
|
|
||||||
cli();
|
cli();
|
||||||
PCMSK3 &=~(1<<PCINT27);
|
PCMSK3 &=~(1<<PCINT27);
|
||||||
sei();
|
sei();
|
||||||
my_system.reset_irq = RESET_IRQ_OFF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void leave_application(void)
|
void leave_application(void)
|
||||||
{
|
{
|
||||||
cli();
|
cli();
|
||||||
usbDeviceDisconnect();
|
usbDeviceDisconnect();
|
||||||
my_system.avr_reset_count++;
|
|
||||||
wdt_enable(WDTO_15MS);
|
wdt_enable(WDTO_15MS);
|
||||||
while (1);
|
while (1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ISR(PCINT3_vect)
|
|
||||||
|
ISR (SIG_PIN_CHANGE3)
|
||||||
{
|
{
|
||||||
if (snes_reset_test()){
|
if (snes_reset_test()){
|
||||||
info_P(PSTR("Catch SNES reset button\n"));
|
info_P(PSTR("Catch SNES reset button\n"));
|
||||||
@ -73,3 +69,4 @@ ISR(PCINT3_vect)
|
|||||||
leave_application();
|
leave_application();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,4 @@
|
|||||||
#ifndef __IRQ_H__
|
#ifndef __IRQ_H__
|
||||||
#define __IRQ_H__
|
#define __IRQ_H__
|
||||||
|
|
||||||
void irq_init();
|
|
||||||
void irq_stop();
|
|
||||||
void leave_application(void);
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
File: %s
|
File: main.smc
|
||||||
Time: %s
|
Time: Thu, 06 Aug 2009 20:01:38
|
||||||
*/
|
*/
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include <loader.h>
|
#include <loader.h>
|
||||||
|
|
||||||
const char _rom01[ROM_BUFFER_SIZE01] PROGMEM = {
|
const char _rom[ROM_BUFFER_SIZE] PROGMEM = {
|
||||||
0x00,0x90,0x04,0x08,0xc2,0x30,0xa9,0x00,0x00,0x20,0x12,0x00,0x20,0xd2,0x08,0x28,0x60,
|
0x00,0x90,0x04,0x08,0xc2,0x30,0xa9,0x00,0x00,0x20,0x12,0x00,0x20,0xd2,0x08,0x28,0x60,
|
||||||
0x08,0xc2,0x31,0x29,0xff,0x00,0x0a,0x0a,0xaa,0xbf,0xe5,0x57,0x7f,0x48,0xbf,0xe3,
|
0x08,0xc2,0x31,0x29,0xff,0x00,0x0a,0x0a,0xaa,0xbf,0xe5,0x57,0x7f,0x48,0xbf,0xe3,
|
||||||
0x57,0x7f,0x48,0xa6,0x8c,0xe2,0x20,0xa9,0x01,0x9f,0x93,0x2d,0x7e,0xa9,0x7f,0x9f,
|
0x57,0x7f,0x48,0xa6,0x8c,0xe2,0x20,0xa9,0x01,0x9f,0x93,0x2d,0x7e,0xa9,0x7f,0x9f,
|
||||||
@ -1951,5 +1951,3 @@ const char _rom01[ROM_BUFFER_SIZE01] PROGMEM = {
|
|||||||
0x00,0x00,0xb7,0xff,0x90,0x05,0xa0,0xff,0x00,0x00,0xa0,0xff,0xa0,0xff,0xa1,0xff,
|
0x00,0x00,0xb7,0xff,0x90,0x05,0xa0,0xff,0x00,0x00,0xa0,0xff,0xa0,0xff,0xa1,0xff,
|
||||||
0xa0,0xff
|
0xa0,0xff
|
||||||
};
|
};
|
||||||
PGM_VOID_P _rom[ROM_BUFFER_CNT]= {&_rom01};
|
|
||||||
const int _rom_size[ROM_BUFFER_CNT] = {31091};
|
|
||||||
|
|||||||
@ -1,15 +1,11 @@
|
|||||||
/*
|
|
||||||
File: qd16boot_ver01.smc
|
|
||||||
Time: Sat, 20 Aug 2016 18:12:14
|
|
||||||
*/
|
|
||||||
#ifndef __FIFO_H__
|
#ifndef __FIFO_H__
|
||||||
#define __FIFO_H__
|
#define __FIFO_H__
|
||||||
|
|
||||||
#define LOADER_NAME "qd16boot_ver01.smc"
|
#define ROM_BUFFER_SIZE 31091
|
||||||
#define LOADER_COMPRESS "RLE"
|
#define ROM_HUFFMAN_SIZE 0
|
||||||
#define ROM_RLE_SIZE 31091
|
#define ROM_RLE_SIZE 31091
|
||||||
#define ROM_BUFFER_CNT 1
|
|
||||||
|
|
||||||
#define ROM_BUFFER_SIZE01 31091
|
void irq_init();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -19,12 +19,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include <avr/eeprom.h>
|
#include <avr/eeprom.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "usbdrv.h"
|
#include "usbdrv.h"
|
||||||
#include "oddebug.h"
|
#include "oddebug.h"
|
||||||
@ -43,20 +44,35 @@
|
|||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "shared_memory.h"
|
#include "shared_memory.h"
|
||||||
#include "irq.h"
|
|
||||||
#include "pwm.h"
|
|
||||||
#include "testing.h"
|
#include "testing.h"
|
||||||
#include "shell.h"
|
|
||||||
#include "system.h"
|
|
||||||
|
|
||||||
#ifndef NO_DEBUG
|
|
||||||
|
|
||||||
|
extern const char _rom[] PROGMEM;
|
||||||
extern FILE uart_stdout;
|
extern FILE uart_stdout;
|
||||||
#endif
|
|
||||||
extern system_t my_system;
|
|
||||||
|
|
||||||
uint8_t debug_level = (DEBUG | DEBUG_USB | DEBUG_CRC);
|
uint8_t debug_level = (DEBUG | DEBUG_USB | DEBUG_CRC | DEBUG_SHM);
|
||||||
|
|
||||||
|
uint8_t read_buffer[TRANSFER_BUFFER_SIZE];
|
||||||
|
uint32_t req_addr = 0;
|
||||||
|
uint32_t req_addr_end = 0;
|
||||||
|
uint32_t req_size;
|
||||||
|
uint8_t req_bank;
|
||||||
|
uint32_t req_bank_size;
|
||||||
|
uint16_t req_bank_cnt;
|
||||||
|
uint8_t req_percent;
|
||||||
|
uint8_t req_percent_last;
|
||||||
|
uint8_t req_state = REQ_STATUS_IDLE;
|
||||||
|
uint8_t rx_remaining = 0;
|
||||||
|
uint8_t tx_remaining = 0;
|
||||||
|
uint16_t sync_errors = 0;
|
||||||
|
uint8_t tx_buffer[32];
|
||||||
|
uint8_t data_buffer[4];
|
||||||
|
uint32_t addr;
|
||||||
|
uint16_t crc = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
usb_transaction_t usb_trans;
|
|
||||||
|
|
||||||
usbMsgLen_t usbFunctionSetup(uchar data[8])
|
usbMsgLen_t usbFunctionSetup(uchar data[8])
|
||||||
{
|
{
|
||||||
@ -66,68 +82,53 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
|
|
||||||
if (rq->bRequest == USB_BULK_UPLOAD_INIT) {
|
if (rq->bRequest == USB_BULK_UPLOAD_INIT) {
|
||||||
|
|
||||||
usb_trans.req_bank = 0;
|
req_bank = 0;
|
||||||
usb_trans.rx_remaining = 0;
|
rx_remaining = 0;
|
||||||
debug_P(DEBUG_USB, PSTR("USB_BULK_UPLOAD_INIT: %i %i\n"),
|
debug_P(DEBUG_USB, PSTR("USB_BULK_UPLOAD_INIT: %i %i\n"), rq->wValue.word,
|
||||||
rq->wValue.word, rq->wIndex.word);
|
rq->wIndex.word);
|
||||||
usb_trans.req_bank_size = (uint32_t) (1L << rq->wValue.word);
|
req_bank_size = (uint32_t) (1L << rq->wValue.word);
|
||||||
usb_trans.req_bank_cnt = rq->wIndex.word;
|
req_bank_cnt = rq->wIndex.word;
|
||||||
usb_trans.req_addr_end =
|
req_addr_end = (uint32_t) req_bank_size *req_bank_cnt;
|
||||||
(uint32_t) usb_trans.req_bank_size * usb_trans.req_bank_cnt;
|
req_percent = 0;
|
||||||
usb_trans.req_percent = 0;
|
req_percent_last = 0;
|
||||||
usb_trans.req_percent_last = 0;
|
sync_errors = 0;
|
||||||
usb_trans.sync_errors = 0;
|
|
||||||
debug_P(DEBUG_USB,
|
debug_P(DEBUG_USB,
|
||||||
PSTR
|
PSTR("USB_BULK_UPLOAD_INIT: bank_size=0x%08lx bank_cnt=0x%x end_addr=0x%08lx\n"),
|
||||||
("USB_BULK_UPLOAD_INIT: bank_size=0x%08lx bank_cnt=0x%x end_addr=0x%08lx\n"),
|
req_bank_size, req_bank_cnt, req_addr_end);
|
||||||
usb_trans.req_bank_size, usb_trans.req_bank_cnt,
|
|
||||||
usb_trans.req_addr_end);
|
|
||||||
|
|
||||||
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_START, 0);
|
shared_memory_write(SHARED_MEM_TX_CMD_BANK_COUNT, req_bank_cnt);
|
||||||
shared_memory_write(SHARED_MEM_TX_CMD_BANK_COUNT,
|
if (req_addr == 0x000000) {
|
||||||
usb_trans.req_bank_cnt);
|
|
||||||
#if DO_TIMER
|
|
||||||
if (usb_trans.req_addr == 0x000000) {
|
|
||||||
#ifndef NO_DEBUG
|
|
||||||
timer_start();
|
timer_start();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
} else if (rq->bRequest == USB_BULK_UPLOAD_ADDR) {
|
} else if (rq->bRequest == USB_BULK_UPLOAD_ADDR) {
|
||||||
|
|
||||||
usb_trans.req_state = REQ_STATUS_BULK_UPLOAD;
|
req_state = REQ_STATUS_BULK_UPLOAD;
|
||||||
usb_trans.req_addr = rq->wValue.word;
|
req_addr = rq->wValue.word;
|
||||||
usb_trans.req_addr = usb_trans.req_addr << 16;
|
req_addr = req_addr << 16;
|
||||||
usb_trans.req_addr = usb_trans.req_addr | rq->wIndex.word;
|
req_addr = req_addr | rq->wIndex.word;
|
||||||
usb_trans.rx_remaining = rq->wLength.word;
|
rx_remaining = rq->wLength.word;
|
||||||
|
|
||||||
|
|
||||||
|
if (req_addr && req_addr % req_bank_size == 0) {
|
||||||
if (usb_trans.req_addr
|
|
||||||
&& usb_trans.req_addr % usb_trans.req_bank_size == 0) {
|
|
||||||
#if DO_TIMER
|
|
||||||
#ifndef NO_DEBUG
|
|
||||||
#ifdef FLT_DEBUG
|
#ifdef FLT_DEBUG
|
||||||
debug_P(DEBUG_USB,
|
debug_P(DEBUG_USB,
|
||||||
PSTR
|
PSTR("USB_BULK_UPLOAD_ADDR: req_bank=0x%02x addr=0x%08lx time=%.4f\n"),
|
||||||
("USB_BULK_UPLOAD_ADDR: req_bank=0x%02x addr=0x%08lx time=%.4f\n"),
|
req_bank, req_addr, timer_stop());
|
||||||
usb_trans.req_bank, usb_trans.req_addr, timer_stop());
|
|
||||||
#else
|
#else
|
||||||
debug_P(DEBUG_USB,
|
debug_P(DEBUG_USB,
|
||||||
PSTR
|
PSTR("USB_BULK_UPLOAD_ADDR: req_bank=0x%02x addr=0x%08lx time=%i\n"),
|
||||||
("USB_BULK_UPLOAD_ADDR: req_bank=0x%02x addr=0x%08lx time=%i\n"),
|
req_bank, req_addr, timer_stop_int());
|
||||||
usb_trans.req_bank, usb_trans.req_addr, timer_stop_int());
|
|
||||||
#endif
|
#endif
|
||||||
|
req_bank++;
|
||||||
|
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_PROGESS, req_bank);
|
||||||
|
sram_bulk_write_start(req_addr);
|
||||||
timer_start();
|
timer_start();
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
usb_trans.req_bank++;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
sram_bulk_write_start(usb_trans.req_addr);
|
sram_bulk_write_start(req_addr);
|
||||||
}
|
}
|
||||||
ret_len = USB_MAX_TRANS;
|
ret_len = USB_MAX_TRANS;
|
||||||
|
|
||||||
@ -135,86 +136,97 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
} else if (rq->bRequest == USB_BULK_UPLOAD_NEXT) {
|
} else if (rq->bRequest == USB_BULK_UPLOAD_NEXT) {
|
||||||
usb_trans.req_state = REQ_STATUS_BULK_UPLOAD;
|
|
||||||
usb_trans.req_addr = rq->wValue.word;
|
|
||||||
usb_trans.req_addr = usb_trans.req_addr << 16;
|
|
||||||
usb_trans.req_addr = usb_trans.req_addr | rq->wIndex.word;
|
|
||||||
usb_trans.rx_remaining = rq->wLength.word;
|
|
||||||
|
|
||||||
#if DO_SHM
|
req_state = REQ_STATUS_BULK_UPLOAD;
|
||||||
usb_trans.req_percent =
|
req_addr = rq->wValue.word;
|
||||||
(uint32_t) (100 * usb_trans.req_addr) / usb_trans.req_addr_end;
|
req_addr = req_addr << 16;
|
||||||
if (usb_trans.req_percent != usb_trans.req_percent_last) {
|
req_addr = req_addr | rq->wIndex.word;
|
||||||
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_PROGESS,
|
rx_remaining = rq->wLength.word;
|
||||||
usb_trans.req_percent);
|
|
||||||
|
req_percent = (uint32_t)( 100 * req_addr ) / req_addr_end;
|
||||||
|
if (req_percent!=req_percent_last){
|
||||||
|
//debug_P(DEBUG_USB,
|
||||||
|
// PSTR("USB_BULK_UPLOAD_ADDR: precent=%i\n", req_percent);
|
||||||
|
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_PROGESS, req_percent);
|
||||||
|
sram_bulk_write_start(req_addr);
|
||||||
}
|
}
|
||||||
usb_trans.req_percent_last = usb_trans.req_percent;
|
req_percent_last = req_percent;
|
||||||
shared_memory_scratchpad_region_save_helper(usb_trans.req_addr);
|
|
||||||
|
#if 0
|
||||||
|
if (req_addr && (req_addr % 0x1000) == 0) {
|
||||||
|
debug_P(DEBUG_USB,
|
||||||
|
PSTR("USB_BULK_UPLOAD_NEXT: bank=0x%02x addr=0x%08lx crc=%04x\n",
|
||||||
|
req_bank, req_addr, crc_check_bulk_memory(req_addr - 0x1000,
|
||||||
|
req_addr,
|
||||||
|
req_bank_size));
|
||||||
|
|
||||||
|
}
|
||||||
|
sram_bulk_write_start(req_addr);
|
||||||
#endif
|
#endif
|
||||||
if (usb_trans.req_addr
|
|
||||||
&& (usb_trans.req_addr % usb_trans.req_bank_size) == 0) {
|
#if SHM_SCRATCHPAD
|
||||||
#if DO_TIMER
|
if (!shared_memory_scratchpad_region_save_helper(req_addr)){
|
||||||
#ifndef NO_DEBUG
|
debug_P(DEBUG_USB,
|
||||||
|
PSTR("USB_BULK_UPLOAD_NEXT: scratchpad_region_save_helper was dirty\n"));
|
||||||
|
sram_bulk_write_start(req_addr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
if (req_addr && (req_addr % req_bank_size) == 0) {
|
||||||
#ifdef FLT_DEBUG
|
#ifdef FLT_DEBUG
|
||||||
debug_P(DEBUG_USB,
|
debug_P(DEBUG_USB,
|
||||||
PSTR
|
PSTR("USB_BULK_UPLOAD_NEXT: req_bank=0x%02x addr=0x%08lx time=%.4f\n"),
|
||||||
("USB_BULK_UPLOAD_NEXT: req_bank=0x%02x addr=0x%08lx time=%.4f\n"),
|
req_bank, req_addr, timer_stop());
|
||||||
usb_trans.req_bank, usb_trans.req_addr, timer_stop());
|
|
||||||
#else
|
#else
|
||||||
debug_P(DEBUG_USB,
|
debug_P(DEBUG_USB,
|
||||||
PSTR
|
PSTR("USB_BULK_UPLOAD_NEXT: req_bank=0x%02x addr=0x%08lx time=%i\n"),
|
||||||
("USB_BULK_UPLOAD_NEXT: req_bank=0x%02x addr=0x%08lx time=%i\n"),
|
req_bank, req_addr, timer_stop_int());
|
||||||
usb_trans.req_bank, usb_trans.req_addr, timer_stop_int());
|
|
||||||
#endif
|
#endif
|
||||||
|
req_bank++;
|
||||||
timer_start();
|
timer_start();
|
||||||
#endif
|
shared_memory_write(SHARED_MEM_TX_CMD_BANK_CURRENT, req_bank);
|
||||||
#endif
|
sram_bulk_write_start(req_addr);
|
||||||
usb_trans.req_bank++;
|
|
||||||
#if DO_SHM
|
|
||||||
shared_memory_write(SHARED_MEM_TX_CMD_BANK_CURRENT,
|
|
||||||
usb_trans.req_bank);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
ret_len = USB_MAX_TRANS;
|
ret_len = USB_MAX_TRANS;
|
||||||
/*
|
/*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
} else if (rq->bRequest == USB_BULK_UPLOAD_END) {
|
} else if (rq->bRequest == USB_BULK_UPLOAD_END) {
|
||||||
|
if (req_state != REQ_STATUS_BULK_UPLOAD) {
|
||||||
|
debug_P(DEBUG_USB,
|
||||||
|
PSTR("USB_BULK_UPLOAD_END: ERROR state is not REQ_STATUS_BULK_UPLOAD\n"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
debug_P(DEBUG_USB, PSTR("USB_BULK_UPLOAD_END:\n"));
|
debug_P(DEBUG_USB, PSTR("USB_BULK_UPLOAD_END:\n"));
|
||||||
usb_trans.req_state = REQ_STATUS_IDLE;
|
req_state = REQ_STATUS_IDLE;
|
||||||
sram_bulk_write_end();
|
sram_bulk_write_end();
|
||||||
#if DO_SHM
|
|
||||||
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_END, 0);
|
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_END, 0);
|
||||||
#endif
|
|
||||||
ret_len = 0;
|
ret_len = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
} else if (rq->bRequest == USB_CRC) {
|
} else if (rq->bRequest == USB_CRC) {
|
||||||
usb_trans.req_addr = rq->wValue.word;
|
req_addr = rq->wValue.word;
|
||||||
usb_trans.req_addr = usb_trans.req_addr << 16;
|
req_addr = req_addr << 16;
|
||||||
usb_trans.req_addr = usb_trans.req_addr | rq->wIndex.word;
|
req_addr = req_addr | rq->wIndex.word;
|
||||||
debug_P(DEBUG_USB, PSTR("USB_CRC: addr=0x%08lx \n"),
|
debug_P(DEBUG_USB, PSTR("USB_CRC: addr=0x%08lx \n"), req_addr);
|
||||||
usb_trans.req_addr);
|
crc_check_bulk_memory(0x000000, req_addr, req_bank_size);
|
||||||
#if DO_CRC_CHECK
|
|
||||||
crc_check_bulk_memory(0x000000, usb_trans.req_addr,
|
|
||||||
usb_trans.req_bank_size);
|
|
||||||
#endif
|
|
||||||
ret_len = 0;
|
ret_len = 0;
|
||||||
/*
|
/*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
} else if (rq->bRequest == USB_MODE_SNES) {
|
} else if (rq->bRequest == USB_MODE_SNES) {
|
||||||
usb_trans.req_state = REQ_STATUS_SNES;
|
req_state = REQ_STATUS_SNES;
|
||||||
debug_P(DEBUG_USB, PSTR("USB_MODE_SNES:\n"));
|
debug_P(DEBUG_USB, PSTR("USB_MODE_SNES:\n"));
|
||||||
ret_len = 0;
|
ret_len = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
} else if (rq->bRequest == USB_MODE_AVR) {
|
} else if (rq->bRequest == USB_MODE_AVR) {
|
||||||
usb_trans.req_state = REQ_STATUS_AVR;
|
req_state = REQ_STATUS_AVR;
|
||||||
debug_P(DEBUG_USB, PSTR("USB_MODE_AVR:\n"));
|
debug_P(DEBUG_USB, PSTR("USB_MODE_AVR:\n"));
|
||||||
ret_len = 0;
|
ret_len = 0;
|
||||||
/*
|
/*
|
||||||
@ -227,102 +239,185 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
/*
|
/*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
} else if (rq->bRequest == USB_SET_LAODER) {
|
|
||||||
debug_P(DEBUG_USB, PSTR("USB_SET_LAODER:\n"));
|
} else if (rq->bRequest == USB_CRC_ADDR) {
|
||||||
usb_trans.loader_enabled = rq->wValue.word;
|
req_state = REQ_STATUS_CRC;
|
||||||
ret_len = 0;
|
req_addr = rq->wValue.word;
|
||||||
|
req_addr = req_addr << 16;
|
||||||
|
req_addr = req_addr | rq->wIndex.word;
|
||||||
|
debug_P(DEBUG_USB, PSTR("USB_CRC_ADDR: addr=0x%lx size=%i\n"), req_addr,
|
||||||
|
rq->wLength.word);
|
||||||
|
req_size = rq->wLength.word;
|
||||||
|
req_size = req_size << 2;
|
||||||
|
tx_remaining = 2;
|
||||||
|
debug_P(DEBUG_USB, PSTR("USB_CRC_ADDR: addr=0x%lx size=%li\n"), req_addr,
|
||||||
|
req_size);
|
||||||
|
|
||||||
|
crc = crc_check_memory_range(req_addr, req_size, read_buffer);
|
||||||
|
tx_buffer[0] = crc & 0xff;
|
||||||
|
tx_buffer[1] = (crc >> 8) & 0xff;
|
||||||
|
ret_len = 2;
|
||||||
|
req_state = REQ_STATUS_IDLE;
|
||||||
}
|
}
|
||||||
usbMsgPtr = usb_trans.rx_buffer;
|
|
||||||
return ret_len;
|
usbMsgPtr = data_buffer;
|
||||||
|
return ret_len; /* default for not implemented requests: return no data back to host */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
void globals_init()
|
void usb_connect()
|
||||||
{
|
{
|
||||||
memset(&usb_trans, 0, sizeof(usb_transaction_t));
|
uint8_t i = 0;
|
||||||
|
info_P(PSTR("USB init\n"));
|
||||||
|
usbDeviceDisconnect(); /* enforce re-enumeration, do this while */
|
||||||
|
cli();
|
||||||
|
info_P(PSTR("USB disconnect\n"));
|
||||||
|
i = 10;
|
||||||
|
while (--i) { /* fake USB disconnect for > 250 ms */
|
||||||
|
led_on();
|
||||||
|
_delay_ms(15);
|
||||||
|
led_off();
|
||||||
|
_delay_ms(35);
|
||||||
|
}
|
||||||
|
led_on();
|
||||||
|
usbDeviceConnect();
|
||||||
|
info_P(PSTR("USB connect\n"));
|
||||||
|
}
|
||||||
|
|
||||||
usb_trans.req_addr = 0;
|
|
||||||
usb_trans.req_addr_end = 0;
|
void boot_startup_rom()
|
||||||
usb_trans.req_state = REQ_STATUS_IDLE;
|
{
|
||||||
usb_trans.rx_remaining = 0;
|
info_P(PSTR("Boot startup rom\n"));
|
||||||
usb_trans.tx_remaining = 0;
|
info_P(PSTR("Activate AVR bus\n"));
|
||||||
usb_trans.sync_errors = 0;
|
avr_bus_active();
|
||||||
usb_trans.loader_enabled = 1;
|
info_P(PSTR("IRQ off\n"));
|
||||||
|
snes_irq_lo();
|
||||||
|
snes_irq_off();
|
||||||
|
snes_lorom();
|
||||||
|
rle_decode(&_rom, ROM_BUFFER_SIZE, 0x000000);
|
||||||
|
info_P(PSTR("\n"));
|
||||||
|
#if 1
|
||||||
|
dump_memory(0x10000 - 0x100, 0x10000);
|
||||||
|
#endif
|
||||||
|
snes_hirom();
|
||||||
|
snes_wr_disable();
|
||||||
|
snes_bus_active();
|
||||||
|
info_P(PSTR("Activate SNES bus\n"));
|
||||||
|
send_reset();
|
||||||
|
_delay_ms(50);
|
||||||
|
send_reset();
|
||||||
|
_delay_ms(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
void banner(){
|
||||||
|
uint8_t i;
|
||||||
|
for (i=0;i<40;i++)
|
||||||
|
info_P(PSTR("\n"));
|
||||||
|
info_P(PSTR(" ________ .__ __ ________ ____ ________\n"));
|
||||||
|
info_P(PSTR(" \\_____ \\ __ __|__| ____ | | __\\______ \\ _______ _/_ |/ _____/\n"));
|
||||||
|
info_P(PSTR(" / / \\ \\| | \\ |/ ___\\| |/ / | | \\_/ __ \\ \\/ /| / __ \\ \n"));
|
||||||
|
info_P(PSTR(" / \\_/. \\ | / \\ \\___| < | ` \\ ___/\\ / | \\ |__\\ \\ \n"));
|
||||||
|
info_P(PSTR(" \\_____\\ \\_/____/|__|\\___ >__|_ \\/_______ /\\___ >\\_/ |___|\\_____ / \n"));
|
||||||
|
info_P(PSTR(" \\__> \\/ \\/ \\/ \\/ \\/ \n"));
|
||||||
|
info_P(PSTR("\n"));
|
||||||
|
info_P(PSTR(" www.optixx.org\n"));
|
||||||
|
info_P(PSTR("\n"));
|
||||||
|
info_P(PSTR("System Hw: %s Sw: %s\n"),HW_VERSION,SW_VERSION);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void globals_init(){
|
||||||
|
req_addr = 0;
|
||||||
|
req_addr_end = 0;
|
||||||
|
req_state = REQ_STATUS_IDLE;
|
||||||
|
rx_remaining = 0;
|
||||||
|
tx_remaining = 0;
|
||||||
|
sync_errors = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifndef NO_DEBUG
|
|
||||||
uart_init();
|
uart_init();
|
||||||
stdout = &uart_stdout;
|
stdout = &uart_stdout;
|
||||||
banner();
|
banner();
|
||||||
#endif
|
|
||||||
shared_memory_init();
|
|
||||||
system_init();
|
system_init();
|
||||||
sram_init();
|
snes_reset_hi();
|
||||||
pwm_init();
|
snes_reset_off();
|
||||||
irq_init();
|
irq_init();
|
||||||
boot_startup_rom(50);
|
boot_startup_rom();
|
||||||
globals_init();
|
globals_init();
|
||||||
pwm_stop();
|
|
||||||
usbInit();
|
usbInit();
|
||||||
usb_connect();
|
usb_connect();
|
||||||
sei();
|
|
||||||
while (1) {
|
while (1) {
|
||||||
system_set_bus_avr();
|
avr_bus_active();
|
||||||
system_set_wr_disable();
|
info_P(PSTR("Activate AVR bus\n"));
|
||||||
while (usb_trans.req_state != REQ_STATUS_SNES) {
|
snes_lorom();
|
||||||
|
info_P(PSTR("Disable SNES WR\n"));
|
||||||
|
snes_wr_disable();
|
||||||
|
sei();
|
||||||
|
info_P(PSTR("USB poll\n"));
|
||||||
|
while (req_state != REQ_STATUS_SNES) {
|
||||||
usbPoll();
|
usbPoll();
|
||||||
#if DO_SHELL
|
|
||||||
#ifndef NO_DEBUG
|
|
||||||
shell_run();
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DO_SHM
|
|
||||||
shared_memory_write(SHARED_MEM_TX_CMD_TERMINATE, 0);
|
shared_memory_write(SHARED_MEM_TX_CMD_TERMINATE, 0);
|
||||||
#endif
|
|
||||||
|
|
||||||
#if DO_SHM_SCRATCHPAD
|
#if SHM_SCRATCHPAD
|
||||||
shared_memory_scratchpad_region_tx_restore();
|
shared_memory_scratchpad_region_tx_restore();
|
||||||
shared_memory_scratchpad_region_rx_restore();
|
shared_memory_scratchpad_region_rx_restore();
|
||||||
#endif
|
#endif
|
||||||
|
info_P(PSTR("USB poll done\n"));
|
||||||
#if DO_CRC_CHECK
|
set_rom_mode();
|
||||||
info_P(PSTR("-->CRC Check\n"));
|
snes_wr_disable();
|
||||||
crc_check_bulk_memory(0x000000,
|
info_P(PSTR("Disable SNES WR\n"));
|
||||||
usb_trans.req_bank_size * usb_trans.req_bank_cnt,
|
snes_bus_active();
|
||||||
usb_trans.req_bank_size);
|
info_P(PSTR("Activate SNES bus\n"));
|
||||||
#endif
|
|
||||||
|
|
||||||
system_set_rom_mode(&usb_trans);
|
|
||||||
system_set_wr_disable();
|
|
||||||
system_set_bus_snes();
|
|
||||||
system_send_snes_reset();
|
|
||||||
irq_stop();
|
irq_stop();
|
||||||
while ((usb_trans.req_state != REQ_STATUS_AVR)) {
|
send_reset();
|
||||||
|
info_P(PSTR("Poll USB\n"));
|
||||||
|
while ((req_state != REQ_STATUS_AVR)) {
|
||||||
usbPoll();
|
usbPoll();
|
||||||
#if DO_SHELL
|
|
||||||
#ifndef NO_DEBUG
|
#ifdef DO_IRQ
|
||||||
shell_run();
|
uint8_t i;
|
||||||
#endif
|
uint16_t irq_count = 0;
|
||||||
#endif
|
i = 10;
|
||||||
|
while (--i) {
|
||||||
|
_delay_ms(100);
|
||||||
}
|
}
|
||||||
info_P(PSTR("-->Switch TO AVR\n"));
|
info_P(PSTR("Send IRQ %i\n"), ++irq_count);
|
||||||
shared_memory_init();
|
send_irq();
|
||||||
irq_init();
|
#endif
|
||||||
if (usb_trans.loader_enabled) {
|
|
||||||
boot_startup_rom(50);
|
#ifdef DO_BUS_STEALING
|
||||||
|
avr_bus_active();
|
||||||
|
sram_bulk_read_start(0x003000);
|
||||||
|
c = sram_bulk_read();
|
||||||
|
i = 5;
|
||||||
|
while (--i) {
|
||||||
|
_delay_ms(500);
|
||||||
|
info_P(PSTR("Wait to switch to snes mode %i\n"), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req_bank_size == 0x8000) {
|
||||||
|
snes_lorom();
|
||||||
} else {
|
} else {
|
||||||
system_set_bus_avr();
|
snes_hirom();
|
||||||
system_send_snes_reset();
|
|
||||||
}
|
}
|
||||||
|
snes_wr_disable();
|
||||||
|
info_P(PSTR("Disable SNES WR\n"));
|
||||||
|
snes_bus_active();
|
||||||
|
info_P(PSTR("Activate SNES bus\n"));
|
||||||
|
info_P(PSTR("Read 0x3000=%c\n"), c);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
irq_init();
|
||||||
|
boot_startup_rom();
|
||||||
globals_init();
|
globals_init();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -1,30 +0,0 @@
|
|||||||
|
|
||||||
Loader Version 1
|
|
||||||
|
|
||||||
DEBUG:
|
|
||||||
Bootloader: 4096
|
|
||||||
CODE: 24984
|
|
||||||
RAM: 742
|
|
||||||
LOADER: 31091
|
|
||||||
|
|
||||||
NO_DEBUG:
|
|
||||||
Bootloader: 4096
|
|
||||||
CODE: 7532
|
|
||||||
RAM: 344
|
|
||||||
LOADER: 31091
|
|
||||||
|
|
||||||
|
|
||||||
Loader Version 2
|
|
||||||
|
|
||||||
DEBUG:
|
|
||||||
Bootloader: 4096
|
|
||||||
CODE: 24984
|
|
||||||
RAM: 742
|
|
||||||
LOADER: 58046
|
|
||||||
|
|
||||||
NO_DEBUG:
|
|
||||||
Bootloader: 4096
|
|
||||||
CODE: 7532
|
|
||||||
RAM: 344
|
|
||||||
LOADER: 58046
|
|
||||||
|
|
||||||
@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
* =====================================================================================
|
|
||||||
*
|
|
||||||
* ________ .__ __ ________ ____ ________
|
|
||||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
* \__> \/ \/ \/ \/ \/
|
|
||||||
*
|
|
||||||
* www.optixx.org
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Version: 1.0
|
|
||||||
* Created: 07/21/2009 03:32:16 PM
|
|
||||||
* Author: david@optixx.org
|
|
||||||
*
|
|
||||||
* =====================================================================================
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
|
|
||||||
#include "pwm.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "info.h"
|
|
||||||
#include "sram.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define PWM_SINE_MAX 64
|
|
||||||
#define PWM_OVERFLOW_MAX 1024
|
|
||||||
|
|
||||||
uint8_t pwm_sine_table[] = {
|
|
||||||
0x7f, 0x8b, 0x97, 0xa4, 0xaf, 0xbb, 0xc5, 0xcf, 0xd9, 0xe1, 0xe8, 0xef,
|
|
||||||
0xf4, 0xf8, 0xfb, 0xfd,
|
|
||||||
0xfd, 0xfd, 0xfb, 0xf8, 0xf3, 0xee, 0xe7, 0xe0, 0xd7, 0xce, 0xc4, 0xb9,
|
|
||||||
0xae, 0xa2, 0x96, 0x89,
|
|
||||||
0x7e, 0x71, 0x65, 0x59, 0x4d, 0x42, 0x37, 0x2d, 0x24, 0x1c, 0x15, 0x0f,
|
|
||||||
0x09, 0x05, 0x03, 0x01,
|
|
||||||
0x01, 0x01, 0x03, 0x07, 0x0b, 0x11, 0x17, 0x1f, 0x28, 0x31, 0x3b, 0x46,
|
|
||||||
0x52, 0x5e, 0x6a, 0x76
|
|
||||||
};
|
|
||||||
|
|
||||||
volatile uint8_t pwm_setting;
|
|
||||||
volatile uint16_t pwm_overflow;
|
|
||||||
volatile uint8_t pwm_idx;
|
|
||||||
volatile uint16_t pwm_overflow_max;
|
|
||||||
|
|
||||||
ISR(TIMER2_COMPA_vect)
|
|
||||||
{
|
|
||||||
static uint8_t pwm_cnt = 0;
|
|
||||||
OCR2A += (uint16_t) T_PWM;
|
|
||||||
|
|
||||||
if (pwm_setting > pwm_cnt)
|
|
||||||
led_pwm_on();
|
|
||||||
else
|
|
||||||
led_pwm_off();
|
|
||||||
|
|
||||||
if (pwm_cnt == (uint8_t) (PWM_STEPS - 1))
|
|
||||||
pwm_cnt = 0;
|
|
||||||
else
|
|
||||||
pwm_cnt++;
|
|
||||||
if (pwm_overflow_max == pwm_overflow++) {
|
|
||||||
pwm_setting = pwm_sine_table[pwm_idx++];
|
|
||||||
pwm_overflow = 0;
|
|
||||||
if (PWM_SINE_MAX == pwm_idx)
|
|
||||||
pwm_idx = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void pwm_speed(uint16_t val)
|
|
||||||
{
|
|
||||||
pwm_overflow_max = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pwm_speed_slow(uint16_t val)
|
|
||||||
{
|
|
||||||
pwm_overflow_max = PWM_OVERFLOW_MAX * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pwm_speed_fast(uint16_t val)
|
|
||||||
{
|
|
||||||
pwm_overflow_max = PWM_OVERFLOW_MAX / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pwm_speed_normal(uint16_t val)
|
|
||||||
{
|
|
||||||
pwm_overflow_max = PWM_OVERFLOW_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void pwm_set(uint8_t val)
|
|
||||||
{
|
|
||||||
pwm_setting = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pwm_stop(void)
|
|
||||||
{
|
|
||||||
while (pwm_setting != 0xfd);
|
|
||||||
TIMSK2 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pwm_init(void)
|
|
||||||
{
|
|
||||||
pwm_overflow_max = PWM_OVERFLOW_MAX;
|
|
||||||
pwm_setting = 0x7f;
|
|
||||||
pwm_overflow = 0;
|
|
||||||
// cli();
|
|
||||||
TCCR2B = 1;
|
|
||||||
TIMSK2 |= (1 << OCIE2A);
|
|
||||||
sei();
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* =====================================================================================
|
|
||||||
*
|
|
||||||
* ________ .__ __ ________ ____ ________
|
|
||||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
* \__> \/ \/ \/ \/ \/
|
|
||||||
*
|
|
||||||
* www.optixx.org
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Version: 1.0
|
|
||||||
* Created: 07/21/2009 03:32:16 PM
|
|
||||||
* Author: david@optixx.org
|
|
||||||
*
|
|
||||||
* =====================================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __PWM_H__
|
|
||||||
#define __PWM_H__
|
|
||||||
|
|
||||||
#define F_PWM 100 // PWM-Frequenz in Hz
|
|
||||||
#define PWM_STEPS 256 // PWM-Schritte pro Zyklus(1..256)
|
|
||||||
|
|
||||||
#define T_PWM (F_CPU/(F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt
|
|
||||||
|
|
||||||
#if (T_PWM<(93+5))
|
|
||||||
#error T_PWM zu klein, F_CPU muss vergrösst werden oder F_PWM oder PWM_STEPS verkleinert werden
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void pwm_init(void);
|
|
||||||
void pwm_stop(void);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -38,23 +38,5 @@
|
|||||||
#define USB_MODE_SNES 10
|
#define USB_MODE_SNES 10
|
||||||
#define USB_MODE_AVR 11
|
#define USB_MODE_AVR 11
|
||||||
#define USB_AVR_RESET 12
|
#define USB_AVR_RESET 12
|
||||||
#define USB_SET_LAODER 13
|
|
||||||
|
|
||||||
typedef struct usb_transaction_t {
|
|
||||||
uint32_t req_addr;
|
|
||||||
uint32_t req_addr_end;
|
|
||||||
uint8_t req_bank;
|
|
||||||
uint32_t req_bank_size;
|
|
||||||
uint16_t req_bank_cnt;
|
|
||||||
uint8_t req_percent;
|
|
||||||
uint8_t req_percent_last;
|
|
||||||
uint8_t req_state;
|
|
||||||
uint8_t rx_remaining;
|
|
||||||
uint8_t tx_remaining;
|
|
||||||
uint16_t sync_errors;
|
|
||||||
uint8_t tx_buffer[32];
|
|
||||||
uint8_t rx_buffer[8];
|
|
||||||
uint8_t loader_enabled;
|
|
||||||
} usb_transaction_t;
|
|
||||||
|
|
||||||
#endif /* __REQUESTS_H_INCLUDED__ */
|
#endif /* __REQUESTS_H_INCLUDED__ */
|
||||||
|
|||||||
@ -1,42 +0,0 @@
|
|||||||
#ifndef _ringbuffer_h
|
|
||||||
#define _ringbuffer_h
|
|
||||||
|
|
||||||
int __mod(int a, int b)
|
|
||||||
{
|
|
||||||
int r = a % b;
|
|
||||||
return r < 0 ? r + b : r;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ring_buffer_typedef(T, NAME) \
|
|
||||||
typedef struct { \
|
|
||||||
int size; \
|
|
||||||
int start; \
|
|
||||||
int end; \
|
|
||||||
T* elems; \
|
|
||||||
} NAME
|
|
||||||
|
|
||||||
#define buffer_init(BUF, S, T) \
|
|
||||||
BUF.size = S+1; \
|
|
||||||
BUF.start = 0; \
|
|
||||||
BUF.end = 0; \
|
|
||||||
BUF.elems = (T*)calloc(BUF.size, sizeof(T))
|
|
||||||
|
|
||||||
|
|
||||||
#define buffer_destroy(BUF) free(BUF->elems)
|
|
||||||
#define nex_start_index(BUF) ((BUF->start + 1) % BUF->size)
|
|
||||||
#define is_buffer_empty(BUF) (BUF->end == BUF->start)
|
|
||||||
#define buffer_get(BUF, INDEX) (BUF->elems[__mod(BUF->end - INDEX, BUF->size)])
|
|
||||||
|
|
||||||
#define bufferWrite(BUF, ELEM) \
|
|
||||||
BUF->elems[BUF->end] = ELEM; \
|
|
||||||
BUF->end = (BUF->end + 1) % BUF->size; \
|
|
||||||
if (is_buffer_empty(BUF)) { \
|
|
||||||
BUF->start = nex_start_index(BUF); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define bufferRead(BUF, ELEM) \
|
|
||||||
ELEM = BUF->elems[BUF->start]; \
|
|
||||||
BUF->start = nex_start_index(BUF);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@ -32,12 +32,14 @@
|
|||||||
|
|
||||||
#define RUNCHAR 0x90
|
#define RUNCHAR 0x90
|
||||||
|
|
||||||
uint32_t rle_decode(PGM_VOID_P in_addr, int32_t in_len, uint32_t out_addr)
|
uint8_t rle_decode(PGM_VOID_P in_addr, int32_t in_len, uint32_t out_addr)
|
||||||
{
|
{
|
||||||
uint8_t in_byte, in_repeat, last_byte;
|
uint8_t in_byte, in_repeat, last_byte;
|
||||||
|
uint32_t out_len, out_len_left;
|
||||||
info_P(PSTR("RLE decode len=%li addr=0x%08lx\n"), in_len, out_addr);
|
info_P(PSTR("RLE decode len=%li addr=0x%08lx\n"), in_len, out_addr);
|
||||||
last_byte = 0;
|
last_byte = 0;
|
||||||
|
|
||||||
|
out_len_left = out_len;
|
||||||
sram_bulk_write_start(out_addr);
|
sram_bulk_write_start(out_addr);
|
||||||
#define INBYTE(b) \
|
#define INBYTE(b) \
|
||||||
do { \
|
do { \
|
||||||
@ -97,6 +99,5 @@ uint32_t rle_decode(PGM_VOID_P in_addr, int32_t in_len, uint32_t out_addr)
|
|||||||
last_byte = in_byte;
|
last_byte = in_byte;
|
||||||
}
|
}
|
||||||
sram_bulk_write_end();
|
sram_bulk_write_end();
|
||||||
info_P(PSTR("\nDone addr=0x%08lx\n"), out_addr);
|
return 0;
|
||||||
return out_addr;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,6 @@
|
|||||||
|
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
uint32_t rle_decode(PGM_VOID_P in_addr, uint32_t in_len, uint32_t out_addr);
|
uint8_t rle_decode(PGM_VOID_P in_addr, uint32_t in_len, uint32_t out_addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -31,8 +31,6 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "dump.h"
|
#include "dump.h"
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
#include "crc.h"
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t irq_addr_lo;
|
uint8_t irq_addr_lo;
|
||||||
uint8_t irq_addr_hi;
|
uint8_t irq_addr_hi;
|
||||||
@ -48,153 +46,83 @@ uint8_t scratchpad_locked_rx = 1;
|
|||||||
uint8_t scratchpad_locked_tx = 1;
|
uint8_t scratchpad_locked_tx = 1;
|
||||||
|
|
||||||
|
|
||||||
void shared_memory_init(void)
|
uint8_t shared_memory_scratchpad_region_save_helper(uint32_t addr){
|
||||||
{
|
|
||||||
scratchpad_locked_rx = 1;
|
|
||||||
scratchpad_locked_tx = 1;
|
|
||||||
|
|
||||||
}
|
if(addr > (SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE) && scratchpad_locked_tx){
|
||||||
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_save_helper: open tx addr=0x%06lx\n"),addr);
|
||||||
|
|
||||||
uint8_t shared_memory_scratchpad_region_save_helper(uint32_t addr)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if DO_SHM_SCRATCHPAD
|
|
||||||
if (addr > (SHARED_MEM_TX_LOC_STATE + (SHARED_MEM_TX_LOC_SIZE))
|
|
||||||
&& scratchpad_locked_tx) {
|
|
||||||
debug_P(DEBUG_SHM,
|
|
||||||
PSTR
|
|
||||||
("shared_memory_scratchpad_region_save_helper: open tx addr=0x%06lx\n"),
|
|
||||||
addr);
|
|
||||||
shared_memory_scratchpad_region_tx_save();
|
shared_memory_scratchpad_region_tx_save();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (addr > (SHARED_MEM_RX_LOC_STATE + (SHARED_MEM_RX_LOC_SIZE))
|
if(addr > (SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE) && scratchpad_locked_rx){
|
||||||
&& scratchpad_locked_rx) {
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_save_helper: open rx addr=0x%06lx\n"),addr);
|
||||||
debug_P(DEBUG_SHM,
|
|
||||||
PSTR
|
|
||||||
("shared_memory_scratchpad_region_save_helper: open rx addr=0x%06lx\n"),
|
|
||||||
addr);
|
|
||||||
shared_memory_scratchpad_region_rx_save();
|
shared_memory_scratchpad_region_rx_save();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void shared_memory_scratchpad_region_tx_save()
|
void shared_memory_scratchpad_region_tx_save()
|
||||||
{
|
{
|
||||||
sram_bulk_addr_save();
|
#if 0
|
||||||
|
|
||||||
#if SHARED_SCRATCHPAD_CRC
|
|
||||||
uint16_t crc;
|
uint16_t crc;
|
||||||
crc = crc_check_bulk_memory((uint32_t)SHARED_MEM_TX_LOC_STATE,
|
crc = crc_check_bulk_memory((uint32_t)SHARED_MEM_TX_LOC_STATE,
|
||||||
(uint32_t) (SHARED_MEM_TX_LOC_STATE +
|
(uint32_t)(SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE), 0x8000);
|
||||||
SHARED_MEM_TX_LOC_SIZE), 0x8000);
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_save: crc=%x\n"),crc);
|
||||||
debug_P(DEBUG_SHM,
|
|
||||||
PSTR("shared_memory_scratchpad_region_tx_save: crc=%x\n"), crc);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
debug_P(DEBUG_SHM,
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_save: unlock\n"));
|
||||||
PSTR("shared_memory_scratchpad_region_tx_save: unlock\n"));
|
sram_bulk_copy_into_buffer((uint32_t)SHARED_MEM_TX_LOC_STATE,scratchpad_region_tx,
|
||||||
sram_bulk_copy_into_buffer((uint32_t) SHARED_MEM_TX_LOC_STATE,
|
|
||||||
scratchpad_region_tx,
|
|
||||||
(uint32_t)SHARED_MEM_TX_LOC_SIZE);
|
(uint32_t)SHARED_MEM_TX_LOC_SIZE);
|
||||||
scratchpad_locked_tx = 0;
|
scratchpad_locked_tx = 0;
|
||||||
|
|
||||||
#if SHARED_SCRATCHPAD_CRC
|
#if 0
|
||||||
do_crc_update(0, scratchpad_region_tx, SHARED_MEM_TX_LOC_SIZE);
|
dump_packet(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_LOC_SIZE, scratchpad_region_tx);
|
||||||
debug_P(DEBUG_SHM,
|
dump_memory(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE);
|
||||||
PSTR("shared_memory_scratchpad_region_tx_save: crc=%x\n"), crc);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SHARED_SCRATCHPAD_DUMP
|
|
||||||
dump_packet(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_LOC_SIZE,
|
|
||||||
scratchpad_region_tx);
|
|
||||||
dump_memory(SHARED_MEM_TX_LOC_STATE,
|
|
||||||
SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE);
|
|
||||||
#endif
|
|
||||||
sram_bulk_addr_restore();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void shared_memory_scratchpad_region_rx_save()
|
void shared_memory_scratchpad_region_rx_save()
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
sram_bulk_addr_save();
|
|
||||||
#if SHARED_SCRATCHPAD_CRC
|
|
||||||
uint16_t crc;
|
uint16_t crc;
|
||||||
crc = crc_check_bulk_memory((uint32_t)SHARED_MEM_RX_LOC_STATE,
|
crc = crc_check_bulk_memory((uint32_t)SHARED_MEM_RX_LOC_STATE,
|
||||||
(uint32_t) (SHARED_MEM_RX_LOC_STATE +
|
(uint32_t)(SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE), 0x8000);
|
||||||
SHARED_MEM_RX_LOC_SIZE), 0x8000);
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_save: crc=%x\n"),crc);
|
||||||
debug_P(DEBUG_SHM,
|
|
||||||
PSTR("shared_memory_scratchpad_region_rx_save: crc=%x\n"), crc);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
debug_P(DEBUG_SHM,
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_rx_save: unlock\n"));
|
||||||
PSTR("shared_memory_scratchpad_region_rx_save: unlock\n"));
|
sram_bulk_copy_into_buffer((uint32_t)SHARED_MEM_RX_LOC_STATE,scratchpad_region_rx,
|
||||||
sram_bulk_copy_into_buffer((uint32_t) SHARED_MEM_RX_LOC_STATE,
|
|
||||||
scratchpad_region_rx,
|
|
||||||
(uint32_t)SHARED_MEM_RX_LOC_SIZE);
|
(uint32_t)SHARED_MEM_RX_LOC_SIZE);
|
||||||
scratchpad_locked_rx = 0;
|
scratchpad_locked_rx = 0;
|
||||||
|
|
||||||
#if SHARED_SCRATCHPAD_CRC
|
#if 0
|
||||||
do_crc_update(0, scratchpad_region_rx, SHARED_MEM_RX_LOC_SIZE);
|
dump_packet(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_RX_LOC_SIZE, scratchpad_region_tx);
|
||||||
debug_P(DEBUG_SHM,
|
dump_memory(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE);
|
||||||
PSTR("shared_memory_scratchpad_region_rx_save: crc=%x\n"), crc);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SHARED_SCRATCHPAD_DUMP
|
|
||||||
dump_packet(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_RX_LOC_SIZE,
|
|
||||||
scratchpad_region_rx);
|
|
||||||
dump_memory(SHARED_MEM_RX_LOC_STATE,
|
|
||||||
SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE);
|
|
||||||
#endif
|
|
||||||
sram_bulk_addr_restore();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void shared_memory_scratchpad_region_tx_restore()
|
void shared_memory_scratchpad_region_tx_restore()
|
||||||
{
|
{
|
||||||
if (scratchpad_locked_tx)
|
if (scratchpad_locked_tx)
|
||||||
return;
|
return;
|
||||||
debug_P(DEBUG_SHM,
|
|
||||||
PSTR("shared_memory_scratchpad_region_tx_restore: lock\n"));
|
|
||||||
|
|
||||||
#if SHARED_SCRATCHPAD_DUMP
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_restore: lock\n"));
|
||||||
debug_P(DEBUG_SHM,
|
sram_bulk_copy_from_buffer((uint32_t)SHARED_MEM_TX_LOC_STATE,scratchpad_region_tx,
|
||||||
PSTR("shared_memory_scratchpad_region_tx_restore: memory\n"));
|
|
||||||
dump_memory(SHARED_MEM_TX_LOC_STATE,
|
|
||||||
SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sram_bulk_copy_from_buffer((uint32_t) SHARED_MEM_TX_LOC_STATE,
|
|
||||||
scratchpad_region_tx,
|
|
||||||
(uint32_t)SHARED_MEM_TX_LOC_SIZE);
|
(uint32_t)SHARED_MEM_TX_LOC_SIZE);
|
||||||
scratchpad_locked_tx = 1;
|
scratchpad_locked_tx = 1;
|
||||||
|
#if 0
|
||||||
#if SHARED_SCRATCHPAD_DUMP
|
dump_packet(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_LOC_SIZE, scratchpad_region_tx);
|
||||||
debug_P(DEBUG_SHM,
|
dump_memory(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE);
|
||||||
PSTR("shared_memory_scratchpad_region_tx_restore: buffer\n"));
|
|
||||||
dump_packet(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_LOC_SIZE,
|
|
||||||
scratchpad_region_tx);
|
|
||||||
debug_P(DEBUG_SHM,
|
|
||||||
PSTR("shared_memory_scratchpad_region_tx_restore: memory\n"));
|
|
||||||
dump_memory(SHARED_MEM_TX_LOC_STATE,
|
|
||||||
SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SHARED_SCRATCHPAD_CRC
|
#if 0
|
||||||
uint16_t crc;
|
uint16_t crc;
|
||||||
crc = crc_check_bulk_memory((uint32_t)SHARED_MEM_TX_LOC_STATE,
|
crc = crc_check_bulk_memory((uint32_t)SHARED_MEM_TX_LOC_STATE,
|
||||||
(uint32_t) (SHARED_MEM_TX_LOC_STATE +
|
(uint32_t)(SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE), 0x8000);
|
||||||
SHARED_MEM_TX_LOC_SIZE), 0x8000);
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_restore: crc=%x\n"),crc);
|
||||||
debug_P(DEBUG_SHM,
|
|
||||||
PSTR("shared_memory_scratchpad_region_tx_restore: crc=%x\n"), crc);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,41 +131,21 @@ void shared_memory_scratchpad_region_rx_restore()
|
|||||||
{
|
{
|
||||||
if (scratchpad_locked_rx)
|
if (scratchpad_locked_rx)
|
||||||
return;
|
return;
|
||||||
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_save: lock\n"));
|
||||||
|
sram_bulk_copy_from_buffer((uint32_t)SHARED_MEM_RX_LOC_STATE,scratchpad_region_rx,
|
||||||
debug_P(DEBUG_SHM,
|
|
||||||
PSTR("shared_memory_scratchpad_region_rx_restore: lock\n"));
|
|
||||||
|
|
||||||
#if SHARED_SCRATCHPAD_DUMP
|
|
||||||
debug_P(DEBUG_SHM,
|
|
||||||
PSTR("shared_memory_scratchpad_region_rx_restore: memory\n"));
|
|
||||||
dump_memory(SHARED_MEM_RX_LOC_STATE - 0x10,
|
|
||||||
SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sram_bulk_copy_from_buffer((uint32_t) SHARED_MEM_RX_LOC_STATE,
|
|
||||||
scratchpad_region_rx,
|
|
||||||
(uint32_t)SHARED_MEM_RX_LOC_SIZE);
|
(uint32_t)SHARED_MEM_RX_LOC_SIZE);
|
||||||
scratchpad_locked_rx = 1;
|
scratchpad_locked_rx = 1;
|
||||||
|
|
||||||
#if SHARED_SCRATCHPAD_DUMP
|
#if 0
|
||||||
debug_P(DEBUG_SHM,
|
dump_packet(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_TX_LOC_SIZE, scratchpad_region_rx);
|
||||||
PSTR("shared_memory_scratchpad_region_rx_restore: buffer\n"));
|
dump_memory(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_TX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE);
|
||||||
dump_packet(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_RX_LOC_SIZE,
|
|
||||||
scratchpad_region_rx);
|
|
||||||
debug_P(DEBUG_SHM,
|
|
||||||
PSTR("shared_memory_scratchpad_region_rx_restore: memory\n"));
|
|
||||||
dump_memory(SHARED_MEM_RX_LOC_STATE - 0x10,
|
|
||||||
SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SHARED_SCRATCHPAD_CRC
|
#if 1
|
||||||
uint16_t crc;
|
uint16_t crc;
|
||||||
crc = crc_check_bulk_memory((uint32_t)SHARED_MEM_RX_LOC_STATE,
|
crc = crc_check_bulk_memory((uint32_t)SHARED_MEM_RX_LOC_STATE,
|
||||||
(uint32_t) (SHARED_MEM_RX_LOC_STATE +
|
(uint32_t)(SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE), 0x8000);
|
||||||
SHARED_MEM_RX_LOC_SIZE), 0x8000);
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_rx_restore: crc=%x\n"),crc);
|
||||||
debug_P(DEBUG_SHM,
|
|
||||||
PSTR("shared_memory_scratchpad_region_rx_restore: crc=%x\n"), crc);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,25 +181,16 @@ void shared_memory_irq_restore()
|
|||||||
|
|
||||||
void shared_memory_write(uint8_t cmd, uint8_t value)
|
void shared_memory_write(uint8_t cmd, uint8_t value)
|
||||||
{
|
{
|
||||||
#if DO_SHM
|
|
||||||
#if DO_SHM_SCRATCHPAD
|
if (scratchpad_locked_tx)
|
||||||
if (scratchpad_locked_tx) {
|
|
||||||
debug_P(DEBUG_SHM, PSTR("shared_memory_write: locked_tx\n"));
|
debug_P(DEBUG_SHM, PSTR("shared_memory_write: locked_tx\n"));
|
||||||
return;
|
|
||||||
}
|
debug_P(DEBUG_SHM, PSTR("shared_memory_write: 0x%04x=0x%02x 0x%04x=0x%02x \n"),
|
||||||
#endif
|
|
||||||
debug_P(DEBUG_SHM,
|
|
||||||
PSTR("shared_memory_write: 0x%04x=0x%02x 0x%04x=0x%02x \n"),
|
|
||||||
SHARED_MEM_TX_LOC_CMD, cmd, SHARED_MEM_TX_LOC_PAYLOAD, value);
|
SHARED_MEM_TX_LOC_CMD, cmd, SHARED_MEM_TX_LOC_PAYLOAD, value);
|
||||||
|
|
||||||
sram_bulk_addr_save();
|
sram_bulk_addr_save();
|
||||||
|
|
||||||
#if (DO_SHM_SCRATCHPAD==0)
|
|
||||||
shared_memory_scratchpad_tx_save();
|
shared_memory_scratchpad_tx_save();
|
||||||
#endif
|
|
||||||
#if SHARED_MEM_SWITCH_IRQ
|
|
||||||
shared_memory_irq_hook();
|
shared_memory_irq_hook();
|
||||||
#endif
|
|
||||||
|
|
||||||
sram_write(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_SNES_ACK);
|
sram_write(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_SNES_ACK);
|
||||||
sram_write(SHARED_MEM_TX_LOC_CMD, cmd);
|
sram_write(SHARED_MEM_TX_LOC_CMD, cmd);
|
||||||
@ -317,14 +216,10 @@ void shared_memory_write(uint8_t cmd, uint8_t value)
|
|||||||
snes_lorom();
|
snes_lorom();
|
||||||
snes_wr_disable();
|
snes_wr_disable();
|
||||||
|
|
||||||
#if (DO_SHM_SCRATCHPAD==0)
|
|
||||||
shared_memory_scratchpad_tx_restore();
|
shared_memory_scratchpad_tx_restore();
|
||||||
#endif
|
|
||||||
#if SHARED_MEM_SWITCH_IRQ
|
|
||||||
shared_memory_irq_restore();
|
shared_memory_irq_restore();
|
||||||
#endif
|
//sram_bulk_addr_restore();
|
||||||
sram_bulk_addr_restore();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void shared_memory_yield()
|
void shared_memory_yield()
|
||||||
@ -343,26 +238,21 @@ void shared_memory_yield()
|
|||||||
|
|
||||||
int shared_memory_read(uint8_t *cmd, uint8_t *len,uint8_t *buffer)
|
int shared_memory_read(uint8_t *cmd, uint8_t *len,uint8_t *buffer)
|
||||||
{
|
{
|
||||||
// uint8_t state;
|
uint8_t state;
|
||||||
#if DO_SHM
|
|
||||||
#if DO_SHM_SCRATCHPAD
|
if (scratchpad_locked_rx)
|
||||||
if (scratchpad_locked_rx) {
|
|
||||||
debug_P(DEBUG_SHM, PSTR("shared_memory_write: locked_tx\n"));
|
debug_P(DEBUG_SHM, PSTR("shared_memory_write: locked_tx\n"));
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
sram_bulk_addr_save();
|
|
||||||
|
|
||||||
state = sram_read(SHARED_MEM_RX_LOC_STATE);
|
state = sram_read(SHARED_MEM_RX_LOC_STATE);
|
||||||
if (state != SHARED_MEM_RX_AVR_ACK){
|
if (state != SHARED_MEM_RX_AVR_ACK){
|
||||||
sram_bulk_addr_restore();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
sram_bulk_addr_save();
|
||||||
|
|
||||||
*cmd = sram_read(SHARED_MEM_RX_LOC_CMD);
|
*cmd = sram_read(SHARED_MEM_RX_LOC_CMD);
|
||||||
*len = sram_read(SHARED_MEM_RX_LOC_LEN);
|
*len = sram_read(SHARED_MEM_RX_LOC_LEN);
|
||||||
debug_P(DEBUG_SHM,
|
debug_P(DEBUG_SHM, PSTR("shared_memory_read: 0x%04x=0x%02x 0x%04x=0x%02x \n"),
|
||||||
PSTR("shared_memory_read: 0x%04x=0x%02x 0x%04x=0x%02x \n"),
|
|
||||||
SHARED_MEM_RX_LOC_CMD, *cmd, SHARED_MEM_RX_LOC_LEN, *len);
|
SHARED_MEM_RX_LOC_CMD, *cmd, SHARED_MEM_RX_LOC_LEN, *len);
|
||||||
|
|
||||||
sram_bulk_copy_into_buffer(SHARED_MEM_RX_LOC_PAYLOAD,buffer, *len);
|
sram_bulk_copy_into_buffer(SHARED_MEM_RX_LOC_PAYLOAD,buffer, *len);
|
||||||
@ -386,6 +276,5 @@ int shared_memory_read(uint8_t * cmd, uint8_t * len, uint8_t * buffer)
|
|||||||
snes_lorom();
|
snes_lorom();
|
||||||
snes_wr_disable();
|
snes_wr_disable();
|
||||||
sram_bulk_addr_restore();
|
sram_bulk_addr_restore();
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,17 +56,12 @@
|
|||||||
#define SHARED_IRQ_LOC_LO 0x00fffe
|
#define SHARED_IRQ_LOC_LO 0x00fffe
|
||||||
#define SHARED_IRQ_LOC_HI 0x00ffff
|
#define SHARED_IRQ_LOC_HI 0x00ffff
|
||||||
|
|
||||||
/*
|
/* Use COP IRQ LOC for hooked IRQ handler */
|
||||||
* Use COP IRQ LOC for hooked IRQ handler
|
|
||||||
*/
|
|
||||||
#define SHARED_IRQ_HANDLER_LO 0x0ffe4
|
#define SHARED_IRQ_HANDLER_LO 0x0ffe4
|
||||||
#define SHARED_IRQ_HANDLER_HI 0x0ffe5
|
#define SHARED_IRQ_HANDLER_HI 0x0ffe5
|
||||||
|
|
||||||
#define SHARED_SCRATCHPAD_DUMP 0
|
|
||||||
#define SHARED_SCRATCHPAD_CRC 0
|
|
||||||
|
|
||||||
|
|
||||||
void shared_memory_init(void);
|
|
||||||
uint8_t shared_memory_scratchpad_region_save_helper(uint32_t addr);
|
uint8_t shared_memory_scratchpad_region_save_helper(uint32_t addr);
|
||||||
void shared_memory_scratchpad_region_tx_save();
|
void shared_memory_scratchpad_region_tx_save();
|
||||||
void shared_memory_scratchpad_region_tx_restore();
|
void shared_memory_scratchpad_region_tx_restore();
|
||||||
|
|||||||
@ -1,495 +0,0 @@
|
|||||||
/*
|
|
||||||
* =====================================================================================
|
|
||||||
*
|
|
||||||
* ________ .__ __ ________ ____ ________
|
|
||||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
* \__> \/ \/ \/ \/ \/
|
|
||||||
*
|
|
||||||
* www.optixx.org
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Version: 1.0
|
|
||||||
* Created: 07/21/2009 03:32:16 PM
|
|
||||||
* Author: david@optixx.org
|
|
||||||
*
|
|
||||||
* =====================================================================================
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
#include <util/delay.h>
|
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
#include <avr/eeprom.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include "pwm.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "info.h"
|
|
||||||
#include "sram.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "uart.h"
|
|
||||||
#include "dump.h"
|
|
||||||
#include "irq.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "crc.h"
|
|
||||||
#include "command.h"
|
|
||||||
#include "shared_memory.h"
|
|
||||||
#include "system.h"
|
|
||||||
|
|
||||||
|
|
||||||
extern system_t my_system;
|
|
||||||
|
|
||||||
const char STR_ROM[] PROGMEM = "Rom";
|
|
||||||
const char STR_RAM[] PROGMEM = "Sram";
|
|
||||||
const char STR_BAT[] PROGMEM = "Battery";
|
|
||||||
const char STR_SUPERFX[] PROGMEM = "SuperFX";
|
|
||||||
const char STR_SA[] PROGMEM = "SA-1";
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t command_buf[RECEIVE_BUF_LEN];
|
|
||||||
uint8_t recv_buf[RECEIVE_BUF_LEN];
|
|
||||||
|
|
||||||
volatile uint8_t recv_counter = 0;
|
|
||||||
volatile uint8_t cr = 0;
|
|
||||||
|
|
||||||
uint8_t *token_ptr;
|
|
||||||
|
|
||||||
#if DO_SHELL
|
|
||||||
|
|
||||||
uint8_t *get_token(void)
|
|
||||||
{
|
|
||||||
uint8_t *p = token_ptr;
|
|
||||||
while (*p == ' ')
|
|
||||||
p++;
|
|
||||||
if (*p == '\0')
|
|
||||||
return NULL;
|
|
||||||
token_ptr = p;
|
|
||||||
do {
|
|
||||||
token_ptr++;
|
|
||||||
if (*token_ptr == ' ' || *token_ptr == '\n' || *token_ptr == '\r') {
|
|
||||||
*token_ptr++ = '\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (*token_ptr != ' ' && *token_ptr != '\n' && *token_ptr != '\r');
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t get_dec(uint32_t * decval)
|
|
||||||
{
|
|
||||||
const uint8_t *t;
|
|
||||||
t = get_token();
|
|
||||||
if (t != NULL) {
|
|
||||||
int x = util_sscandec(t);
|
|
||||||
if (x < 0)
|
|
||||||
return 0;
|
|
||||||
*decval = x;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t parse_hex(const uint8_t * s, uint32_t * hexval)
|
|
||||||
{
|
|
||||||
uint32_t x = util_sscanhex(s);
|
|
||||||
*hexval = (uint32_t) x;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t get_hex(uint32_t * hexval)
|
|
||||||
{
|
|
||||||
const uint8_t *t;
|
|
||||||
t = get_token();
|
|
||||||
if (t != NULL)
|
|
||||||
return parse_hex(t, hexval);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t get_hex_arg2(uint32_t * hexval1, uint32_t * hexval2)
|
|
||||||
{
|
|
||||||
return get_hex(hexval1) && get_hex(hexval2);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t get_hex_arg3(uint32_t * hexval1, uint32_t * hexval2, uint32_t * hexval3)
|
|
||||||
{
|
|
||||||
return get_hex(hexval1) && get_hex(hexval2) && get_hex(hexval3);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static uint8_t get_int32(uint32_t * val)
|
|
||||||
{
|
|
||||||
if (!get_hex(val)) {
|
|
||||||
info_P(PSTR("Invalid argument!\n"));
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t get_int8(uint8_t * val)
|
|
||||||
{
|
|
||||||
uint32_t ret;
|
|
||||||
if (!get_hex(&ret) || ret > 0xff) {
|
|
||||||
info_P(PSTR("Invalid argument!\n"));
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
*val = (uint8_t) ret;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
static int get_bool(void)
|
|
||||||
{
|
|
||||||
const uint8_t *t;
|
|
||||||
t = get_token();
|
|
||||||
if (t != NULL) {
|
|
||||||
int result = util_sscanbool(t);
|
|
||||||
if (result >= 0)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
info_P(PSTR("Invalid argument (should be 0 or 1)!\n"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
void prompt(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
uart_putc('\r');
|
|
||||||
uart_putc('\n');
|
|
||||||
uart_putc('>');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ISR(USART0_RX_vect)
|
|
||||||
{
|
|
||||||
UCSR0B &= (255 - (1 << RXCIE0)); // Interrupts disable for RxD
|
|
||||||
sei();
|
|
||||||
if (recv_counter == (sizeof(recv_buf) - 1)) {
|
|
||||||
cr = 1;
|
|
||||||
recv_buf[recv_counter] = '\0';
|
|
||||||
recv_counter = 0;
|
|
||||||
prompt();
|
|
||||||
}
|
|
||||||
recv_buf[recv_counter] = UDR0;
|
|
||||||
uart_putc(recv_buf[recv_counter]);
|
|
||||||
if (recv_buf[recv_counter] == 0x0d) {
|
|
||||||
/*
|
|
||||||
* recv_buf[recv_counter] = 0;
|
|
||||||
*/
|
|
||||||
cr = 1;
|
|
||||||
recv_buf[++recv_counter] = '\0';
|
|
||||||
recv_counter = 0;
|
|
||||||
prompt();
|
|
||||||
} else {
|
|
||||||
// we accept backspace or delete
|
|
||||||
if ((recv_buf[recv_counter] == 0x08 || recv_buf[recv_counter] == 0x7f)
|
|
||||||
&& recv_counter > 0) {
|
|
||||||
recv_counter--;
|
|
||||||
} else {
|
|
||||||
recv_counter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UCSR0B |= (1 << RXCIE0);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum cmds {
|
|
||||||
CMD_DUMP,
|
|
||||||
CMD_DUMPVEC,
|
|
||||||
CMD_DUMPHEADER,
|
|
||||||
#if DO_CRC_CHECK
|
|
||||||
CMD_CRC,
|
|
||||||
#endif
|
|
||||||
CMD_EXIT,
|
|
||||||
CMD_RESET,
|
|
||||||
CMD_RESETSNIFF,
|
|
||||||
CMD_IRQ,
|
|
||||||
CMD_AVR,
|
|
||||||
CMD_SNES,
|
|
||||||
CMD_LOROM,
|
|
||||||
CMD_HIROM,
|
|
||||||
CMD_WR,
|
|
||||||
CMD_SHMWR,
|
|
||||||
CMD_SHMSAVE,
|
|
||||||
CMD_SHMRESTORE,
|
|
||||||
CMD_LOADER,
|
|
||||||
CMD_RECONNECT,
|
|
||||||
CMD_STATUS,
|
|
||||||
CMD_SYS,
|
|
||||||
CMD_HELP
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t cmdlist[][CMD_HELP] PROGMEM = {
|
|
||||||
{"DUMP"},
|
|
||||||
{"DUMPVEC"},
|
|
||||||
{"DUMPHEADER"},
|
|
||||||
#if DO_CRC_CHECK
|
|
||||||
{"CRC"},
|
|
||||||
#endif
|
|
||||||
{"EXIT"},
|
|
||||||
{"RESET"},
|
|
||||||
{"RESETSNIFF"},
|
|
||||||
{"IRQ"},
|
|
||||||
{"AVR"},
|
|
||||||
{"SNES"},
|
|
||||||
{"LOROM"},
|
|
||||||
{"HIROM"},
|
|
||||||
{"WR"},
|
|
||||||
{"SHMWR"},
|
|
||||||
{"SHMSAVE"},
|
|
||||||
{"SHMRESTORE"},
|
|
||||||
{"LOADER"},
|
|
||||||
{"RECONNECT"},
|
|
||||||
{"STATUS"},
|
|
||||||
{"SYS"},
|
|
||||||
{"HELP"},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void shell_help(void)
|
|
||||||
{
|
|
||||||
uint8_t i;
|
|
||||||
info_P(PSTR("\n"));
|
|
||||||
for (i = CMD_DUMP; i < CMD_HELP; i++) {
|
|
||||||
info_P((PGM_P) cmdlist[i]);
|
|
||||||
info_P(PSTR("\n"));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void shell_run(void)
|
|
||||||
{
|
|
||||||
uint8_t *t;
|
|
||||||
uint32_t arg1;
|
|
||||||
uint32_t arg2;
|
|
||||||
uint16_t crc;
|
|
||||||
uint16_t offset;
|
|
||||||
uint8_t c;
|
|
||||||
|
|
||||||
if (!cr)
|
|
||||||
return;
|
|
||||||
cr = 0;
|
|
||||||
strcpy((char *) command_buf, (char *) recv_buf);
|
|
||||||
|
|
||||||
token_ptr = command_buf;
|
|
||||||
t = get_token();
|
|
||||||
|
|
||||||
if (t == NULL)
|
|
||||||
shell_help();
|
|
||||||
|
|
||||||
util_strupper(t);
|
|
||||||
|
|
||||||
if (strcmp_P((const char *) t, (PGM_P) cmdlist[CMD_DUMP]) == 0) {
|
|
||||||
if (get_hex_arg2(&arg1, &arg2))
|
|
||||||
dump_memory(arg1, arg2);
|
|
||||||
else
|
|
||||||
info_P(PSTR("DUMP <start addr> <end addr>\n"));
|
|
||||||
|
|
||||||
#if DO_CRC_CHECK
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_CRC]) == 0) {
|
|
||||||
if (get_hex_arg2(&arg1, &arg2)) {
|
|
||||||
crc = crc_check_bulk_memory(arg1, arg2, 0x8000);
|
|
||||||
info_P(PSTR("0x%06lx - 0x%06lx crc=0x%04x\n"), arg1, arg2, crc);
|
|
||||||
} else
|
|
||||||
info_P(PSTR("CRC <start addr> <end addr>\n"));
|
|
||||||
#endif
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_EXIT]) == 0) {
|
|
||||||
leave_application();
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_RESET]) == 0) {
|
|
||||||
system_send_snes_reset();
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_IRQ]) == 0) {
|
|
||||||
info_P(PSTR("Send IRQ\n"));
|
|
||||||
snes_irq_on();
|
|
||||||
snes_irq_lo();
|
|
||||||
_delay_us(20);
|
|
||||||
snes_irq_hi();
|
|
||||||
snes_irq_off();
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_AVR]) == 0) {
|
|
||||||
system_set_bus_avr();
|
|
||||||
snes_irq_lo();
|
|
||||||
system_snes_irq_off();
|
|
||||||
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_SNES]) == 0) {
|
|
||||||
snes_irq_lo();
|
|
||||||
system_snes_irq_off();
|
|
||||||
system_set_wr_disable();
|
|
||||||
system_set_bus_snes();
|
|
||||||
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_LOROM]) == 0) {
|
|
||||||
system_set_rom_lorom();
|
|
||||||
system_set_wr_disable();
|
|
||||||
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_HIROM]) == 0) {
|
|
||||||
system_set_rom_hirom();
|
|
||||||
system_set_wr_disable();
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_WR]) == 0) {
|
|
||||||
arg1 = get_bool();
|
|
||||||
if (arg1 == 1) {
|
|
||||||
info_P(PSTR("Set WR enable"));
|
|
||||||
snes_wr_enable();
|
|
||||||
} else if (arg1 == 0) {
|
|
||||||
info_P(PSTR("Set WR disable"));
|
|
||||||
snes_wr_disable();
|
|
||||||
}
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_RESETSNIFF]) == 0) {
|
|
||||||
arg1 = get_bool();
|
|
||||||
if (arg1 == 1) {
|
|
||||||
info_P(PSTR("Start Reset sniffer"));
|
|
||||||
irq_init();
|
|
||||||
} else if (arg1 == 0) {
|
|
||||||
info_P(PSTR("Stop Reset sniffer"));
|
|
||||||
irq_stop();
|
|
||||||
}
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_DUMPVEC]) == 0) {
|
|
||||||
uint16_t offset;
|
|
||||||
if (my_system.rom_mode == LOROM)
|
|
||||||
offset = 0x8000;
|
|
||||||
else
|
|
||||||
offset = 0x0000;
|
|
||||||
|
|
||||||
info_P(PSTR("ABORT 0x%04x 0x%04x\n"), (0xFFE8 - offset),
|
|
||||||
sram_read16_be(0xFFE8 - offset));
|
|
||||||
info_P(PSTR("BRK 0x%04x 0x%04x\n"), (0xFFE6 - offset),
|
|
||||||
sram_read16_be(0xFFE6 - offset));
|
|
||||||
info_P(PSTR("COP 0x%04x 0x%04x\n"), (0xFFE4 - offset),
|
|
||||||
sram_read16_be(0xFFE4 - offset));
|
|
||||||
info_P(PSTR("IRQ 0x%04x 0x%04x\n"), (0xFFEE - offset),
|
|
||||||
sram_read16_be(0xFFEE - offset));
|
|
||||||
info_P(PSTR("NMI 0x%04x 0x%04x\n"), (0xFFEA - offset),
|
|
||||||
sram_read16_be(0xFFEA - offset));
|
|
||||||
info_P(PSTR("RES 0x%04x 0x%04x\n"), (0xFFFC - offset),
|
|
||||||
sram_read16_be(0xFFFC - offset));
|
|
||||||
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_DUMPHEADER]) == 0) {
|
|
||||||
|
|
||||||
if (my_system.rom_mode == LOROM)
|
|
||||||
offset = 0x8000;
|
|
||||||
else
|
|
||||||
offset = 0x0000;
|
|
||||||
/*
|
|
||||||
* # $ffc0..$ffd4 => Name of the ROM, typically in ASCII, using spaces to pad the name to 21 bytes. # $ffd5 => ROM layout,
|
|
||||||
* typically $20 for LoROM, or $21 for HiROM. Add $10 for FastROM. # $ffd6 => Cartridge type, typically $00 for ROM only, or $02
|
|
||||||
* for ROM with save-RAM. # $ffd7 => ROM size byte. # $ffd8 => RAM size byte. # $ffd9 => Country code, which selects the video in
|
|
||||||
* the emulator. Values $00, $01, $0d use NTSC. Values in range $02..$0c use PAL. Other values are invalid. # $ffda => Licensee
|
|
||||||
* code. If this value is $33, then the ROM has an extended header with ID at $ffb2..$ffb5. # $ffdb => Version number, typically
|
|
||||||
* $00. # $ffdc..$ffdd => Checksum complement, which is the bitwise-xor of the checksum and $ffff. # $ffde..$ffdf => SNES checksum,
|
|
||||||
* an unsigned 16-bit checksum of bytes. # $ffe0..$ffe3 => Unknown.
|
|
||||||
*/
|
|
||||||
info_P(PSTR("NAME 0x%04x "), (0xffc0 - offset));
|
|
||||||
for (arg1 = (0xffc0 - offset); arg1 < (0xffc0 - offset + 21); arg1++) {
|
|
||||||
c = sram_read(arg1);
|
|
||||||
if (c > 0x1f && c < 0x7f)
|
|
||||||
printf("%c", c);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
c = sram_read(0xffd5 - offset);
|
|
||||||
info_P(PSTR("LAYOUT 0x%04x "), (0xffd5 - offset));
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case 0x20:
|
|
||||||
info_P(PSTR("LoROM, not fast\n"));
|
|
||||||
break;
|
|
||||||
case 0x21:
|
|
||||||
info_P(PSTR("HiRom, not fast\n"));
|
|
||||||
break;
|
|
||||||
case 0x30:
|
|
||||||
info_P(PSTR("LoROM, fast\n"));
|
|
||||||
break;
|
|
||||||
case 0x31:
|
|
||||||
info_P(PSTR("HiRom, fast\n"));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
info_P(PSTR("Unkown 0x%02x\n"), c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = sram_read(0xffd6 - offset);
|
|
||||||
info_P(PSTR("TYPE 0x%04xc"), (0xffd6 - offset), c);
|
|
||||||
switch (c) {
|
|
||||||
case 0x00:
|
|
||||||
info_P(PSTR("Rom\n"));
|
|
||||||
break;
|
|
||||||
case 0x01:
|
|
||||||
info_P(PSTR("Rom + Sram\n"));
|
|
||||||
break;
|
|
||||||
case 0x02:
|
|
||||||
info_P(PSTR("Rom + Sram + Battery\n"));
|
|
||||||
break;
|
|
||||||
case 0x13:
|
|
||||||
info_P(PSTR("SuperFX\n"));
|
|
||||||
break;
|
|
||||||
case 0x14:
|
|
||||||
info_P(PSTR("SuperFX\n"));
|
|
||||||
break;
|
|
||||||
case 0x15:
|
|
||||||
info_P(PSTR("SuperFX + Sram\n"));
|
|
||||||
break;
|
|
||||||
case 0x1a:
|
|
||||||
info_P(PSTR("SuperFX + Sram\n"));
|
|
||||||
break;
|
|
||||||
case 0x34:
|
|
||||||
info_P(PSTR("SA-1"));
|
|
||||||
break;
|
|
||||||
case 0x35:
|
|
||||||
info_P(PSTR("SA-1"));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
info_P(PSTR("Unkown 0x%02x\n"), c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
arg1 = (2 << (sram_read(0xffd7 - offset) - 1));
|
|
||||||
info_P(PSTR("ROM 0x%04x %li MBit ( %li KiB)\n"),
|
|
||||||
(0xffd7 - offset), (arg1 / 128), arg1);
|
|
||||||
arg1 = (2 << (sram_read(0xffd8 - offset) - 1));
|
|
||||||
info_P(PSTR("RAM 0x%04x %li KiB\n"), (0xffd8 - offset), arg1);
|
|
||||||
|
|
||||||
info_P(PSTR("CCODE 0x%04x "), (0xffd9 - offset));
|
|
||||||
c = sram_read(0xffd9 - offset);
|
|
||||||
if (c == 0x00 || c == 0x01 || 0x0d)
|
|
||||||
info_P(PSTR("NTSC\n"));
|
|
||||||
else if (c >= 0x02 || c <= 0x0c)
|
|
||||||
info_P(PSTR("PAL\n"));
|
|
||||||
else
|
|
||||||
info_P(PSTR("Unkown 0x%02x\n"), c);
|
|
||||||
|
|
||||||
info_P(PSTR("LIC 0x%04x 0x%02x\n"), (0xffda - offset),
|
|
||||||
sram_read(0xffda - offset));
|
|
||||||
info_P(PSTR("VER 0x%04x 0x%02x\n"), (0xffdb - offset),
|
|
||||||
sram_read(0xffdb - offset));
|
|
||||||
info_P(PSTR("SUM1 0x%04x 0x%04x\n"), (0xffdc - offset),
|
|
||||||
sram_read16_be(0xffdc - offset));
|
|
||||||
info_P(PSTR("SUM2 0x%04x 0x%04x\n"), (0xffde - offset),
|
|
||||||
sram_read16_be(0xffde - offset));
|
|
||||||
|
|
||||||
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_SHMWR]) == 0) {
|
|
||||||
if (get_hex_arg2(&arg1, &arg2))
|
|
||||||
shared_memory_write((uint8_t) arg1, (uint8_t) arg1);
|
|
||||||
else
|
|
||||||
info_P(PSTR("SHMWR <command> <value>\n"));
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_SHMSAVE]) == 0) {
|
|
||||||
shared_memory_scratchpad_region_tx_save();
|
|
||||||
shared_memory_scratchpad_region_rx_save();
|
|
||||||
info_P(PSTR("Save scratchpad\n"));
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_SHMRESTORE]) == 0) {
|
|
||||||
shared_memory_scratchpad_region_tx_restore();
|
|
||||||
shared_memory_scratchpad_region_rx_restore();
|
|
||||||
info_P(PSTR("Restore scratchpad\n"));
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_LOADER]) == 0) {
|
|
||||||
boot_startup_rom(500);
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_RECONNECT]) == 0) {
|
|
||||||
usb_connect();
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_STATUS]) == 0) {
|
|
||||||
transaction_status();
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_SYS]) == 0) {
|
|
||||||
system_status();
|
|
||||||
} else if (strcmp_P((char *) t, (PGM_P) cmdlist[CMD_HELP]) == 0) {
|
|
||||||
shell_help();
|
|
||||||
}
|
|
||||||
prompt();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
* =====================================================================================
|
|
||||||
*
|
|
||||||
* ________ .__ __ ________ ____ ________
|
|
||||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
* \__> \/ \/ \/ \/ \/
|
|
||||||
*
|
|
||||||
* www.optixx.org
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Version: 1.0
|
|
||||||
* Created: 07/21/2009 03:32:16 PM
|
|
||||||
* Author: david@optixx.org
|
|
||||||
*
|
|
||||||
* =====================================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __SHELL_H__
|
|
||||||
#define __SHELL_H__
|
|
||||||
|
|
||||||
void shell_run(void);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -34,7 +34,7 @@
|
|||||||
uint32_t addr_current = 0;
|
uint32_t addr_current = 0;
|
||||||
uint32_t addr_stash = 0;
|
uint32_t addr_stash = 0;
|
||||||
|
|
||||||
void sram_init(void)
|
void system_init(void)
|
||||||
{
|
{
|
||||||
/*-------------------------------------------------*/
|
/*-------------------------------------------------*/
|
||||||
|
|
||||||
@ -114,18 +114,14 @@ void sreg_set(uint32_t addr)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sram_bulk_addr_save()
|
inline void sram_bulk_addr_save()
|
||||||
{
|
{
|
||||||
addr_stash = addr_current;
|
addr_stash = addr_current;
|
||||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_addr_save: addr=0x%08lx\n\r"),
|
|
||||||
addr_stash);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void sram_bulk_addr_restore()
|
inline void sram_bulk_addr_restore()
|
||||||
{
|
{
|
||||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_addr_restore: addr=0x%08lx\n\r"),
|
sreg_set(addr_stash);
|
||||||
addr_stash);
|
|
||||||
sram_bulk_write_start(addr_stash);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -217,17 +213,9 @@ uint8_t sram_read(uint32_t addr)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t sram_read16_be(uint32_t addr)
|
|
||||||
{
|
|
||||||
uint8_t hi = sram_read(addr);
|
|
||||||
uint8_t lo = sram_read(addr + 1);
|
|
||||||
return (hi << 8 | lo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sram_bulk_write_start(uint32_t addr)
|
void sram_bulk_write_start(uint32_t addr)
|
||||||
{
|
{
|
||||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_write_start: addr=0x%08lx\n\r"), addr);
|
debug_P(DEBUG_SRAM, PSTR("sram_bulk_write_start: addr=0x%08lx\n\r"), addr);
|
||||||
addr_current = addr;
|
|
||||||
|
|
||||||
avr_data_out();
|
avr_data_out();
|
||||||
|
|
||||||
@ -237,19 +225,20 @@ void sram_bulk_write_start(uint32_t addr)
|
|||||||
|
|
||||||
sreg_set(addr);
|
sreg_set(addr);
|
||||||
|
|
||||||
|
AVR_WR_PORT &= ~(1 << AVR_WR_PIN);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void sram_bulk_write_next(void)
|
inline void sram_bulk_write_next(void)
|
||||||
{
|
{
|
||||||
addr_current++;
|
AVR_WR_PORT |= (1 << AVR_WR_PIN);
|
||||||
counter_up();
|
counter_up();
|
||||||
|
AVR_WR_PORT &= ~(1 << AVR_WR_PIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void sram_bulk_write( uint8_t data)
|
inline void sram_bulk_write( uint8_t data)
|
||||||
{
|
{
|
||||||
AVR_WR_PORT &= ~(1 << AVR_WR_PIN);
|
|
||||||
AVR_DATA_PORT = data;
|
AVR_DATA_PORT = data;
|
||||||
AVR_WR_PORT |= (1 << AVR_WR_PIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sram_bulk_write_end(void)
|
void sram_bulk_write_end(void)
|
||||||
@ -263,8 +252,7 @@ void sram_bulk_write_end(void)
|
|||||||
|
|
||||||
void sram_write(uint32_t addr, uint8_t data)
|
void sram_write(uint32_t addr, uint8_t data)
|
||||||
{
|
{
|
||||||
debug_P(DEBUG_SRAM_RAW, PSTR("sram_write: addr=0x%08lx data=%x\n\r"), addr,
|
debug_P(DEBUG_SRAM_RAW, PSTR("sram_write: addr=0x%08lx data=%x\n\r"), addr, data);
|
||||||
data);
|
|
||||||
|
|
||||||
avr_data_out();
|
avr_data_out();
|
||||||
|
|
||||||
@ -298,17 +286,12 @@ void sram_bulk_copy_from_buffer(uint32_t addr, uint8_t * src, uint32_t len)
|
|||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint8_t *ptr = src;
|
uint8_t *ptr = src;
|
||||||
debug_P(DEBUG_SRAM,
|
debug_P(DEBUG_SRAM, PSTR("sram_bulk_copy_from_buffer: addr=0x%08lx src=0x%p len=%li\n\r"),
|
||||||
PSTR
|
|
||||||
("sram_bulk_copy_from_buffer: addr=0x%08lx src=0x%p len=%li\n\r"),
|
|
||||||
addr, src, len);
|
addr, src, len);
|
||||||
sram_bulk_write_start(addr);
|
sram_bulk_write_start(addr);
|
||||||
for (i = addr; i < (addr + len); i++){
|
for (i = addr; i < (addr + len); i++){
|
||||||
sram_bulk_write(*ptr);
|
sram_bulk_write(*ptr++);
|
||||||
// hack
|
|
||||||
if ((i + 1) < (addr + len))
|
|
||||||
sram_bulk_write_next();
|
sram_bulk_write_next();
|
||||||
ptr++;
|
|
||||||
}
|
}
|
||||||
sram_bulk_write_end();
|
sram_bulk_write_end();
|
||||||
}
|
}
|
||||||
@ -317,24 +300,21 @@ void sram_bulk_copy_into_buffer(uint32_t addr, uint8_t * dst, uint32_t len)
|
|||||||
{
|
{
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
// uint8_t *ptr = dst;
|
uint8_t *ptr = dst;
|
||||||
debug_P(DEBUG_SRAM,
|
debug_P(DEBUG_SRAM, PSTR("sram_bulk_copy_into_buffer: addr=0x%08lx dst=0x%p len=%li\n\r"),
|
||||||
PSTR
|
|
||||||
("sram_bulk_copy_into_buffer: addr=0x%08lx dst=0x%p len=%li\n\r"),
|
|
||||||
addr, dst, len);
|
addr, dst, len);
|
||||||
sram_bulk_read_start(addr);
|
sram_bulk_read_start(addr);
|
||||||
for (i = addr; i < (addr + len); i++) {
|
for (i = addr; i < (addr + len); i++) {
|
||||||
dst[i] = sram_bulk_read();
|
*ptr = sram_bulk_read();
|
||||||
sram_bulk_read_next();
|
sram_bulk_read_next();
|
||||||
|
ptr++;
|
||||||
}
|
}
|
||||||
sram_bulk_read_end();
|
sram_bulk_read_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sram_bulk_set(uint32_t addr, uint32_t len, uint8_t value)
|
void sram_bulk_set(uint32_t addr, uint32_t len,uint8_t value){
|
||||||
{
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_set: addr=0x%08lx len=%li\n\r"), addr,
|
debug_P(DEBUG_SRAM, PSTR("sram_bulk_set: addr=0x%08lx len=%li\n\r"), addr,len);
|
||||||
len);
|
|
||||||
sram_bulk_write_start(addr);
|
sram_bulk_write_start(addr);
|
||||||
for (i = addr; i < (addr + len); i++) {
|
for (i = addr; i < (addr + len); i++) {
|
||||||
if (0 == i % 0xfff)
|
if (0 == i % 0xfff)
|
||||||
@ -344,3 +324,4 @@ void sram_bulk_set(uint32_t addr, uint32_t len, uint8_t value)
|
|||||||
}
|
}
|
||||||
sram_bulk_write_end();
|
sram_bulk_write_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -29,9 +29,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/* ---------------------------- PORT A ---------------------------- */
|
||||||
* ---------------------------- PORT A ----------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define AVR_DATA_PORT PORTA
|
#define AVR_DATA_PORT PORTA
|
||||||
#define AVR_DATA_DIR DDRA
|
#define AVR_DATA_DIR DDRA
|
||||||
@ -43,9 +41,7 @@
|
|||||||
#define avr_data_out() (AVR_DATA_DIR = 0xff)
|
#define avr_data_out() (AVR_DATA_DIR = 0xff)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/* ---------------------------- PORT B ---------------------------- */
|
||||||
* ---------------------------- PORT B ----------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define AVR_PORT PORTB
|
#define AVR_PORT PORTB
|
||||||
#define AVR_DIR DDRB
|
#define AVR_DIR DDRB
|
||||||
@ -82,9 +78,7 @@
|
|||||||
#define snes_irq_lo() (SNES_IRQ_PORT &= ~(1 << SNES_IRQ_PIN))
|
#define snes_irq_lo() (SNES_IRQ_PORT &= ~(1 << SNES_IRQ_PIN))
|
||||||
|
|
||||||
|
|
||||||
/*
|
/* ---------------------------- PORT C ---------------------------- */
|
||||||
* ---------------------------- PORT C ----------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define AVR_ADDR_PORT PORTC
|
#define AVR_ADDR_PORT PORTC
|
||||||
#define AVR_ADDR_DIR DDRC
|
#define AVR_ADDR_DIR DDRC
|
||||||
@ -92,22 +86,22 @@
|
|||||||
#define AVR_ADDR_LATCH_DIR DDRC
|
#define AVR_ADDR_LATCH_DIR DDRC
|
||||||
#define AVR_ADDR_LATCH_PIN PC6
|
#define AVR_ADDR_LATCH_PIN PC6
|
||||||
|
|
||||||
#define avr_addr_latch_hi() (AVR_ADDR_LATCH_PORT |= (1 << AVR_ADDR_LATCH_PIN))
|
#define avr_addr_latch_hi() (AVR_ADDR_LATCH_PORT |= (1 << AVR_ADDR_LATCH_PIN)))
|
||||||
#define avr_addr_latch_lo() (AVR_ADDR_LATCH_PORT &= ~(1 << AVR_ADDR_LATCH_PIN))
|
#define avr_addr_latch_lo() (AVR_ADDR_LATCH_PORT &= ~(1 << AVR_ADDR_LATCH_PIN)))
|
||||||
|
|
||||||
#define AVR_ADDR_SCK_PORT PORTC
|
#define AVR_ADDR_SCK_PORT PORTC
|
||||||
#define AVR_ADDR_SCK_DIR DDRC
|
#define AVR_ADDR_SCK_DIR DDRC
|
||||||
#define AVR_ADDR_SCK_PIN PC5
|
#define AVR_ADDR_SCK_PIN PC5
|
||||||
|
|
||||||
#define avr_addr_sck_hi() (AVR_ADDR_SCK_PORT |= (1 << AVR_ADDR_SCK_PIN))
|
#define avr_addr_sck_hi() (AVR_ADDR_SCK_PORT |= (1 << AVR_ADDR_SCK_PIN)))
|
||||||
#define avr_addr_sck_lo() (AVR_ADDR_SCK_PORT &= ~(1 << AVR_ADDR_SCK_PIN))
|
#define avr_addr_sck_lo() (AVR_ADDR_SCK_PORT &= ~(1 << AVR_ADDR_SCK_PIN)))
|
||||||
|
|
||||||
#define AVR_ADDR_SER_PORT PORTC
|
#define AVR_ADDR_SER_PORT PORTC
|
||||||
#define AVR_ADDR_SER_DIR DDRC
|
#define AVR_ADDR_SER_DIR DDRC
|
||||||
#define AVR_ADDR_SER_PIN PC4
|
#define AVR_ADDR_SER_PIN PC4
|
||||||
|
|
||||||
#define avr_addr_ser_hi() (AVR_ADDR_SER_PORT |= (1 << AVR_ADDR_SER_PIN))
|
#define avr_addr_ser_hi() (AVR_ADDR_SER_PORT |= (1 << AVR_ADDR_SER_PIN)))
|
||||||
#define avr_addr_ser_lo() (AVR_ADDR_SER_PORT &= ~(1 << AVR_ADDR_SER_PIN))
|
#define avr_addr_ser_lo() (AVR_ADDR_SER_PORT &= ~(1 << AVR_ADDR_SER_PIN)))
|
||||||
|
|
||||||
#define AVR_ADDR_LOAD_PORT PORTC
|
#define AVR_ADDR_LOAD_PORT PORTC
|
||||||
#define AVR_ADDR_LOAD_DIR DDRC
|
#define AVR_ADDR_LOAD_DIR DDRC
|
||||||
@ -143,12 +137,8 @@
|
|||||||
#define led_off() ((LED_PORT &=~ (1 << LED_PIN)),\
|
#define led_off() ((LED_PORT &=~ (1 << LED_PIN)),\
|
||||||
(LED_DIR |= (1 << LED_PIN)))
|
(LED_DIR |= (1 << LED_PIN)))
|
||||||
|
|
||||||
#define led_pwm_on() (LED_DIR &=~ (1 << LED_PIN))
|
|
||||||
#define led_pwm_off() (LED_DIR |= (1 << LED_PIN))
|
|
||||||
|
|
||||||
/*
|
/* ---------------------------- PORT D ---------------------------- */
|
||||||
* ---------------------------- PORT D ----------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define AVR_SNES_PORT PORTD
|
#define AVR_SNES_PORT PORTD
|
||||||
#define AVR_SNES_DIR DDRD
|
#define AVR_SNES_DIR DDRD
|
||||||
@ -161,8 +151,7 @@
|
|||||||
(AVR_CS_DIR |= (1 << AVR_CS_PIN)))
|
(AVR_CS_DIR |= (1 << AVR_CS_PIN)))
|
||||||
|
|
||||||
#define snes_bus_active() ((AVR_SNES_SW_PORT |= (1 << AVR_SNES_SW_PIN)),\
|
#define snes_bus_active() ((AVR_SNES_SW_PORT |= (1 << AVR_SNES_SW_PIN)),\
|
||||||
(AVR_CS_DIR &= ~(1 << AVR_CS_PIN)),\
|
(AVR_CS_DIR &= ~(1 << AVR_CS_PIN)))
|
||||||
(AVR_CS_PORT |= (1 << AVR_CS_PIN)))
|
|
||||||
|
|
||||||
#define HI_LOROM_SW_PORT PORTD
|
#define HI_LOROM_SW_PORT PORTD
|
||||||
#define HI_LOROM_SW_DIR DDRD
|
#define HI_LOROM_SW_DIR DDRD
|
||||||
@ -204,7 +193,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void sram_init(void);
|
void system_init(void);
|
||||||
void sreg_set(uint32_t addr);
|
void sreg_set(uint32_t addr);
|
||||||
|
|
||||||
uint8_t sram_read(uint32_t addr);
|
uint8_t sram_read(uint32_t addr);
|
||||||
@ -214,7 +203,6 @@ void sram_bulk_read_start(uint32_t addr);
|
|||||||
inline void sram_bulk_read_next(void);
|
inline void sram_bulk_read_next(void);
|
||||||
inline void sram_bulk_read_end(void);
|
inline void sram_bulk_read_end(void);
|
||||||
uint8_t sram_bulk_read(void);
|
uint8_t sram_bulk_read(void);
|
||||||
uint16_t sram_read16_be(uint32_t addr);
|
|
||||||
|
|
||||||
void sram_bulk_write_start(uint32_t addr);
|
void sram_bulk_write_start(uint32_t addr);
|
||||||
inline void sram_bulk_write_next(void);
|
inline void sram_bulk_write_next(void);
|
||||||
|
|||||||
@ -1,192 +0,0 @@
|
|||||||
/*
|
|
||||||
* =====================================================================================
|
|
||||||
*
|
|
||||||
* ________ .__ __ ________ ____ ________
|
|
||||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
* \__> \/ \/ \/ \/ \/
|
|
||||||
*
|
|
||||||
* www.optixx.org
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Version: 1.0
|
|
||||||
* Created: 07/21/2009 03:32:16 PM
|
|
||||||
* Author: david@optixx.org
|
|
||||||
*
|
|
||||||
* =====================================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <util/delay.h> /* for _delay_ms() */
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "sram.h"
|
|
||||||
#include "system.h"
|
|
||||||
#include "uart.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "info.h"
|
|
||||||
#include "requests.h"
|
|
||||||
#include "irq.h"
|
|
||||||
|
|
||||||
system_t my_system;
|
|
||||||
|
|
||||||
void system_init(void)
|
|
||||||
{
|
|
||||||
snes_reset_hi();
|
|
||||||
snes_reset_off();
|
|
||||||
my_system.reset_line = RESET_OFF;
|
|
||||||
|
|
||||||
snes_irq_hi();
|
|
||||||
snes_irq_off();
|
|
||||||
my_system.irq_line = IRQ_OFF;
|
|
||||||
|
|
||||||
|
|
||||||
snes_wr_disable();
|
|
||||||
my_system.wr_line = WR_DISABLE;
|
|
||||||
|
|
||||||
avr_bus_active();
|
|
||||||
my_system.bus_mode = MODE_AVR;
|
|
||||||
|
|
||||||
snes_lorom();
|
|
||||||
my_system.rom_mode = LOROM;
|
|
||||||
|
|
||||||
my_system.snes_reset_count = 0;
|
|
||||||
my_system.avr_reset_count = 0;
|
|
||||||
|
|
||||||
my_system.reset_irq = RESET_IRQ_OFF;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void system_send_snes_reset()
|
|
||||||
{
|
|
||||||
info_P(PSTR("Reset SNES\n"));
|
|
||||||
cli();
|
|
||||||
snes_reset_on();
|
|
||||||
snes_reset_lo();
|
|
||||||
_delay_ms(2);
|
|
||||||
snes_reset_hi();
|
|
||||||
snes_reset_off();
|
|
||||||
sei();
|
|
||||||
my_system.snes_reset_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void system_send_snes_irq()
|
|
||||||
{
|
|
||||||
snes_irq_on();
|
|
||||||
snes_irq_lo();
|
|
||||||
_delay_us(20);
|
|
||||||
snes_irq_hi();
|
|
||||||
snes_irq_off();
|
|
||||||
}
|
|
||||||
|
|
||||||
void system_snes_irq_off()
|
|
||||||
{
|
|
||||||
snes_irq_off();
|
|
||||||
my_system.irq_line = IRQ_OFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
void system_snes_irq_on()
|
|
||||||
{
|
|
||||||
snes_irq_on();
|
|
||||||
my_system.irq_line = IRQ_ON;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void system_set_bus_avr()
|
|
||||||
{
|
|
||||||
avr_bus_active();
|
|
||||||
info_P(PSTR("Activate AVR bus\n"));
|
|
||||||
my_system.bus_mode = MODE_AVR;
|
|
||||||
}
|
|
||||||
|
|
||||||
void system_set_wr_disable()
|
|
||||||
{
|
|
||||||
snes_wr_disable();
|
|
||||||
my_system.wr_line = WR_DISABLE;
|
|
||||||
info_P(PSTR("Disable SNES WR\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void system_set_wr_enable()
|
|
||||||
{
|
|
||||||
snes_wr_enable();
|
|
||||||
my_system.wr_line = WR_ENABLE;
|
|
||||||
info_P(PSTR("Enable SNES WR\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void system_set_bus_snes()
|
|
||||||
{
|
|
||||||
snes_bus_active();
|
|
||||||
my_system.bus_mode = MODE_SNES;
|
|
||||||
info_P(PSTR("Activate SNES bus\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void system_set_rom_mode(usb_transaction_t * usb_trans)
|
|
||||||
{
|
|
||||||
if (usb_trans->req_bank_size == 0x8000) {
|
|
||||||
snes_lorom();
|
|
||||||
my_system.rom_mode = LOROM;
|
|
||||||
info_P(PSTR("Set SNES lorom \n"));
|
|
||||||
} else {
|
|
||||||
snes_hirom();
|
|
||||||
my_system.rom_mode = HIROM;
|
|
||||||
info_P(PSTR("Set SNES hirom \n"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void system_set_rom_lorom()
|
|
||||||
{
|
|
||||||
snes_lorom();
|
|
||||||
my_system.rom_mode = LOROM;
|
|
||||||
info_P(PSTR("Set SNES lorom \n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void system_set_rom_hirom()
|
|
||||||
{
|
|
||||||
snes_hirom();
|
|
||||||
my_system.rom_mode = HIROM;
|
|
||||||
info_P(PSTR("Set SNES hirom \n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
char *system_status_helper(uint8_t val)
|
|
||||||
{
|
|
||||||
if (val)
|
|
||||||
return "ON";
|
|
||||||
else
|
|
||||||
return "OFF";
|
|
||||||
}
|
|
||||||
|
|
||||||
char *system_status_bus(uint8_t val)
|
|
||||||
{
|
|
||||||
if (val)
|
|
||||||
return "SNES";
|
|
||||||
else
|
|
||||||
return "AVR";
|
|
||||||
}
|
|
||||||
|
|
||||||
char *system_status_rom(uint8_t val)
|
|
||||||
{
|
|
||||||
if (val)
|
|
||||||
return "HIROM";
|
|
||||||
else
|
|
||||||
return "LOROM";
|
|
||||||
}
|
|
||||||
|
|
||||||
void system_status()
|
|
||||||
{
|
|
||||||
info_P(PSTR("\nBus Mode %s\n"), system_status_bus(my_system.bus_mode));
|
|
||||||
info_P(PSTR("Rom Mode %s\n"), system_status_rom(my_system.rom_mode));
|
|
||||||
info_P(PSTR("Reset Line %s\n"),
|
|
||||||
system_status_helper(my_system.reset_line));
|
|
||||||
info_P(PSTR("IRQ Line %s\n"), system_status_helper(my_system.irq_line));
|
|
||||||
info_P(PSTR("WR Line %s\n"), system_status_helper(my_system.wr_line));
|
|
||||||
info_P(PSTR("Reset IRQ %s\n"), system_status_helper(my_system.reset_irq));
|
|
||||||
info_P(PSTR("SNES Reset 0x%02x\n"), my_system.snes_reset_count);
|
|
||||||
info_P(PSTR("AVR Reset 0x%02x\n"), my_system.avr_reset_count);
|
|
||||||
}
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* =====================================================================================
|
|
||||||
*
|
|
||||||
* ________ .__ __ ________ ____ ________
|
|
||||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
* \__> \/ \/ \/ \/ \/
|
|
||||||
*
|
|
||||||
* www.optixx.org
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Version: 1.0
|
|
||||||
* Created: 07/21/2009 03:32:16 PM
|
|
||||||
* Author: david@optixx.org
|
|
||||||
*
|
|
||||||
* =====================================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __SYSTEM_H__
|
|
||||||
#define __SYSTEM_H__
|
|
||||||
|
|
||||||
#include "requests.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct system_t {
|
|
||||||
enum bus_mode_e { MODE_AVR, MODE_SNES } bus_mode;
|
|
||||||
enum rom_mode_e { LOROM, HIROM } rom_mode;
|
|
||||||
enum reset_line_e { RESET_OFF, RESET_ON } reset_line;
|
|
||||||
enum irq_line_e { IRQ_ON, IRQ_OFF } irq_line;
|
|
||||||
enum wr_line_e { WR_DISABLE, WR_ENABLE } wr_line;
|
|
||||||
enum reset_irq_e { RESET_IRQ_OFF, RESET_IRQ_ON } reset_irq;
|
|
||||||
|
|
||||||
uint8_t snes_reset_count;
|
|
||||||
uint8_t avr_reset_count;
|
|
||||||
} system_t;
|
|
||||||
|
|
||||||
void system_init(void);
|
|
||||||
void system_init(void);
|
|
||||||
void system_send_snes_reset(void);
|
|
||||||
void system_send_snes_irq(void);
|
|
||||||
void system_set_bus_avr(void);
|
|
||||||
void system_set_bus_snes(void);
|
|
||||||
void system_set_rom_mode(usb_transaction_t * usb_trans);
|
|
||||||
void system_set_rom_hirom(void);
|
|
||||||
void system_set_rom_lorom(void);
|
|
||||||
void system_snes_irq_off(void);
|
|
||||||
void system_set_wr_disable(void);
|
|
||||||
void system_set_wr_enable(void);
|
|
||||||
|
|
||||||
void system_status();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -31,7 +31,6 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
#include "dump.h"
|
|
||||||
|
|
||||||
void test_read_write()
|
void test_read_write()
|
||||||
{
|
{
|
||||||
@ -93,37 +92,6 @@ void test_non_zero_memory(uint32_t bottom_addr, uint32_t top_addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void test_memory_pattern(uint32_t bottom_addr, uint32_t top_addr,
|
|
||||||
uint32_t bank_size)
|
|
||||||
{
|
|
||||||
uint32_t addr = 0;
|
|
||||||
uint8_t pattern = 0x55;
|
|
||||||
info_P(PSTR("test_memory_pattern: bottom_addr=0x%08lx top_addr=0x%08lx\n"),
|
|
||||||
bottom_addr, top_addr);
|
|
||||||
sram_bulk_write_start(bottom_addr);
|
|
||||||
for (addr = bottom_addr; addr < top_addr; addr++) {
|
|
||||||
if (addr % bank_size == 0) {
|
|
||||||
pattern++;
|
|
||||||
info_P(PSTR
|
|
||||||
("test_memory_pattern: write addr=0x%08lx pattern=0x%08lx\n"),
|
|
||||||
addr, pattern);
|
|
||||||
}
|
|
||||||
sram_bulk_write(pattern);
|
|
||||||
}
|
|
||||||
sram_bulk_write_end();
|
|
||||||
|
|
||||||
|
|
||||||
for (addr = bottom_addr; addr < top_addr; addr += bank_size) {
|
|
||||||
info_P(PSTR
|
|
||||||
("test_memory_pattern: dump bottom_addr=0x%08lx top_addr=0x%08lx\n"),
|
|
||||||
addr, addr + bank_size);
|
|
||||||
dump_memory(addr, addr + bank_size);
|
|
||||||
info_P(PSTR
|
|
||||||
("----------------------------------------------------------------\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
crc_check_bulk_memory((uint32_t) bottom_addr, top_addr, bank_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_crc()
|
void test_crc()
|
||||||
{
|
{
|
||||||
@ -135,3 +103,4 @@ void test_crc()
|
|||||||
info_P(PSTR("test_crc: check\n"));
|
info_P(PSTR("test_crc: check\n"));
|
||||||
test_non_zero_memory(0x000000, 0x10000);
|
test_non_zero_memory(0x000000, 0x10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
|
#include <avr/io.h>
|
||||||
#include <avr/interrupt.h> /* for sei() */
|
#include <avr/interrupt.h> /* for sei() */
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
@ -52,7 +53,8 @@ extern uint8_t snes_reset_line;
|
|||||||
uint16_t prescaler;
|
uint16_t prescaler;
|
||||||
uint16_t volatile second; // count seconds
|
uint16_t volatile second; // count seconds
|
||||||
|
|
||||||
ISR(TIMER1_COMPA_vect)
|
|
||||||
|
ISR (SIG_OUTPUT_COMPARE1A)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
@ -87,3 +89,6 @@ uint16_t timer_stop_int(void)
|
|||||||
uint16_t t = ((DEBOUNCE - prescaler) / DEBOUNCE ) + second;
|
uint16_t t = ((DEBOUNCE - prescaler) / DEBOUNCE ) + second;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -25,8 +25,6 @@
|
|||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "fifo.h"
|
#include "fifo.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
volatile struct {
|
volatile struct {
|
||||||
uint8_t tmr_int:1;
|
uint8_t tmr_int:1;
|
||||||
uint8_t adc_int:1;
|
uint8_t adc_int:1;
|
||||||
@ -37,23 +35,29 @@ volatile struct {
|
|||||||
volatile char rxbuff;
|
volatile char rxbuff;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int uart_stream(char c, FILE * stream);
|
|
||||||
|
|
||||||
FILE uart_stdout = FDEV_SETUP_STREAM(uart_stream, NULL, _FDEV_SETUP_WRITE);
|
FILE uart_stdout = FDEV_SETUP_STREAM(uart_stream, NULL, _FDEV_SETUP_WRITE);
|
||||||
|
|
||||||
void uart_init(void)
|
void uart_init(void)
|
||||||
{
|
{
|
||||||
UCSR0A = _BV(U2X0); /* improves baud rate error @ F_CPU = 1 MHz */
|
UCSR0A = _BV(U2X0); /* improves baud rate error @ F_CPU = 1 MHz */
|
||||||
UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0); /* tx/rx enable, rx complete * intr */
|
UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0); /* tx/rx enable, rx complete
|
||||||
|
* intr */
|
||||||
UBRR0L = (F_CPU / (8 * 115200UL)) - 1;
|
UBRR0L = (F_CPU / (8 * 115200UL)) - 1;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* ISR(USART0_RX_vect) { uint8_t c; c = UDR0; if (bit_is_clear(UCSR0A, FE0)) { rxbuff = c; intflags.rx_int = 1; } }
|
ISR(USART0_RX_vect)
|
||||||
*/
|
{
|
||||||
|
uint8_t c;
|
||||||
|
c = UDR0;
|
||||||
|
if (bit_is_clear(UCSR0A, FE0)) {
|
||||||
|
rxbuff = c;
|
||||||
|
intflags.rx_int = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void uart_putc(uint8_t c)
|
void uart_putc(uint8_t c)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -32,5 +32,9 @@ void uart_init(void);
|
|||||||
void uart_putc(const uint8_t);
|
void uart_putc(const uint8_t);
|
||||||
void uart_puts(const char *s);
|
void uart_puts(const char *s);
|
||||||
void uart_puts_P(PGM_P s);
|
void uart_puts_P(PGM_P s);
|
||||||
|
static int uart_stream(char c, FILE *stream);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "usbdrv.h"
|
#include "usbdrv.h"
|
||||||
#include "oddebug.h" /* This is also an example for using debug macros */
|
#include "oddebug.h" /* This is also an example for using debug
|
||||||
|
* macros */
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "requests.h" /* The custom request numbers we use */
|
#include "requests.h" /* The custom request numbers we use */
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
@ -38,27 +39,32 @@
|
|||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include "usb_bulk.h"
|
#include "usb_bulk.h"
|
||||||
|
|
||||||
|
extern uint8_t read_buffer[TRANSFER_BUFFER_SIZE];
|
||||||
extern usb_transaction_t usb_trans;
|
extern uint32_t req_addr;
|
||||||
|
extern uint32_t req_size;
|
||||||
|
extern uint8_t req_bank;
|
||||||
|
extern uint32_t req_bank_size;
|
||||||
|
extern uint8_t req_state;
|
||||||
|
extern uint8_t rx_remaining;
|
||||||
|
extern uint8_t tx_remaining;
|
||||||
|
extern uint8_t tx_buffer[32];
|
||||||
|
extern uint16_t crc;
|
||||||
|
|
||||||
uint8_t usbFunctionWrite(uint8_t * data, uint8_t len)
|
uint8_t usbFunctionWrite(uint8_t * data, uint8_t len)
|
||||||
{
|
{
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
if (len > usb_trans.rx_remaining) {
|
if (len > rx_remaining) {
|
||||||
info_P(PSTR
|
info_P(PSTR("ERROR:usbFunctionWrite more data than expected remain: %i len: %i\n"),
|
||||||
("ERROR:usbFunctionWrite more data than expected remain: %i len: %i\n"),
|
rx_remaining, len);
|
||||||
usb_trans.rx_remaining, len);
|
len = rx_remaining;
|
||||||
len = usb_trans.rx_remaining;
|
|
||||||
}
|
}
|
||||||
if (usb_trans.req_state == REQ_STATUS_BULK_UPLOAD) {
|
if (req_state == REQ_STATUS_BULK_UPLOAD) {
|
||||||
|
|
||||||
usb_trans.rx_remaining -= len;
|
rx_remaining -= len;
|
||||||
debug_P(DEBUG_USB_TRANS,
|
debug_P(DEBUG_USB_TRANS, PSTR("usbFunctionWrite REQ_STATUS_BULK_UPLOAD addr: 0x%08lx len: %i rx_remaining=%i\n"),
|
||||||
PSTR
|
req_addr, len, rx_remaining);
|
||||||
("usbFunctionWrite REQ_STATUS_BULK_UPLOAD addr: 0x%08lx len: %i rx_remaining=%i\n"),
|
|
||||||
usb_trans.req_addr, len, usb_trans.rx_remaining);
|
|
||||||
ptr = data;
|
ptr = data;
|
||||||
i = len;
|
i = len;
|
||||||
while(i--){
|
while(i--){
|
||||||
@ -72,14 +78,13 @@ uint8_t usbFunctionWrite(uint8_t * data, uint8_t len)
|
|||||||
uint8_t usbFunctionRead(uint8_t * data, uint8_t len)
|
uint8_t usbFunctionRead(uint8_t * data, uint8_t len)
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
if (len > usb_trans.tx_remaining)
|
if (len > tx_remaining)
|
||||||
len = usb_trans.tx_remaining;
|
len = tx_remaining;
|
||||||
usb_trans.tx_remaining -= len;
|
tx_remaining -= len;
|
||||||
debug_P(DEBUG_USB_TRANS, PSTR("usbFunctionRead len=%i tx_remaining=%i \n"),
|
debug_P(DEBUG_USB_TRANS, PSTR("usbFunctionRead len=%i tx_remaining=%i \n"), len, tx_remaining);
|
||||||
len, usb_trans.tx_remaining);
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
*data = usb_trans.tx_buffer[len];
|
*data = tx_buffer[len];
|
||||||
data++;
|
data++;
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
|
|||||||
@ -20,287 +20,325 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/* Name: usbconfig.h
|
||||||
* Name: usbconfig.h Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers Author: Christian Starkjohann Creation Date:
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
* 2005-04-01 Tabsize: 4 Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH License: GNU GPL v2 (see License.txt), GNU GPL v3 or
|
* Author: Christian Starkjohann
|
||||||
* proprietary (CommercialLicense.txt) This Revision: $Id: usbconfig-prototype.h 740 2009-04-13 18:23:31Z cs $
|
* Creation Date: 2005-04-01
|
||||||
|
* Tabsize: 4
|
||||||
|
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: usbconfig-prototype.h 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __usbconfig_h_included__
|
#ifndef __usbconfig_h_included__
|
||||||
#define __usbconfig_h_included__
|
#define __usbconfig_h_included__
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* General Description: This file is an example configuration (with inline documentation) for the USB driver. It configures V-USB for USB
|
General Description:
|
||||||
* D+ connected to Port D bit 2 (which is also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may wire the lines to
|
This file is an example configuration (with inline documentation) for the USB
|
||||||
* any other port, as long as D+ is also wired to INT0 (or any other hardware interrupt, as long as it is the highest level interrupt, see
|
driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
|
||||||
* section at the end of this file).
|
also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
|
||||||
|
wire the lines to any other port, as long as D+ is also wired to INT0 (or any
|
||||||
|
other hardware interrupt, as long as it is the highest level interrupt, see
|
||||||
|
section at the end of this file).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/* ---------------------------- Hardware Config ---------------------------- */
|
||||||
* ---------------------------- Hardware Config ----------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define USB_CFG_IOPORTNAME D
|
#define USB_CFG_IOPORTNAME D
|
||||||
/*
|
/* This is the port where the USB bus is connected. When you configure it to
|
||||||
* This is the port where the USB bus is connected. When you configure it to "B", the registers PORTB, PINB and DDRB will be used.
|
* "B", the registers PORTB, PINB and DDRB will be used.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DMINUS_BIT 4
|
#define USB_CFG_DMINUS_BIT 4
|
||||||
/*
|
/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
|
||||||
* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected. This may be any bit in the port.
|
* This may be any bit in the port.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DPLUS_BIT 2
|
#define USB_CFG_DPLUS_BIT 2
|
||||||
/*
|
/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
|
||||||
* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected. This may be any bit in the port. Please note that D+ must
|
* This may be any bit in the port. Please note that D+ must also be connected
|
||||||
* also be connected to interrupt pin INT0! [You can also use other interrupts, see section "Optional MCU Description" below, or you can
|
* to interrupt pin INT0! [You can also use other interrupts, see section
|
||||||
* connect D- to the interrupt, as it is required if you use the USB_COUNT_SOF feature. If you use D- for the interrupt, the USB interrupt
|
* "Optional MCU Description" below, or you can connect D- to the interrupt, as
|
||||||
* will also be triggered at Start-Of-Frame markers every millisecond.]
|
* it is required if you use the USB_COUNT_SOF feature. If you use D- for the
|
||||||
|
* interrupt, the USB interrupt will also be triggered at Start-Of-Frame
|
||||||
|
* markers every millisecond.]
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
|
#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
|
||||||
/*
|
/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000,
|
||||||
* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000, 16500 and 20000. The 12.8 MHz and 16.5 MHz versions of the
|
* 16500 and 20000. The 12.8 MHz and 16.5 MHz versions of the code require no
|
||||||
* code require no crystal, they tolerate +/- 1% deviation from the nominal frequency. All other rates require a precision of 2000 ppm and
|
* crystal, they tolerate +/- 1% deviation from the nominal frequency. All
|
||||||
* thus a crystal! Default if not specified: 12 MHz
|
* other rates require a precision of 2000 ppm and thus a crystal!
|
||||||
|
* Default if not specified: 12 MHz
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_CHECK_CRC 0
|
#define USB_CFG_CHECK_CRC 0
|
||||||
/*
|
/* Define this to 1 if you want that the driver checks integrity of incoming
|
||||||
* Define this to 1 if you want that the driver checks integrity of incoming data packets (CRC checks). CRC checks cost quite a bit of code
|
* data packets (CRC checks). CRC checks cost quite a bit of code size and are
|
||||||
* size and are currently only available for 18 MHz crystal clock. You must choose USB_CFG_CLOCK_KHZ = 18000 if you enable this option.
|
* currently only available for 18 MHz crystal clock. You must choose
|
||||||
|
* USB_CFG_CLOCK_KHZ = 18000 if you enable this option.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/* ----------------------- Optional Hardware Config ------------------------ */
|
||||||
* ----------------------- Optional Hardware Config ------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
//#define USB_CFG_PULLUP_IOPORTNAME D
|
//#define USB_CFG_PULLUP_IOPORTNAME D
|
||||||
/*
|
/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
|
||||||
* If you connect the 1.5k pullup resistor from D- to a port pin instead of V+, you can connect and disconnect the device from firmware by
|
* V+, you can connect and disconnect the device from firmware by calling
|
||||||
* calling the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h). This constant defines the port on which the pullup
|
* the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
|
||||||
* resistor is connected.
|
* This constant defines the port on which the pullup resistor is connected.
|
||||||
*/
|
*/
|
||||||
//#define USB_CFG_PULLUP_BIT 6
|
//#define USB_CFG_PULLUP_BIT 6
|
||||||
/*
|
/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
|
||||||
* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined above) where the 1.5k pullup resistor is connected. See
|
* above) where the 1.5k pullup resistor is connected. See description
|
||||||
* description above for details.
|
* above for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/* --------------------------- Functional Range ---------------------------- */
|
||||||
* --------------------------- Functional Range ----------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define USB_CFG_HAVE_INTRIN_ENDPOINT 0
|
#define USB_CFG_HAVE_INTRIN_ENDPOINT 0
|
||||||
/*
|
/* Define this to 1 if you want to compile a version with two endpoints: The
|
||||||
* Define this to 1 if you want to compile a version with two endpoints: The default control endpoint 0 and an interrupt-in endpoint (any
|
* default control endpoint 0 and an interrupt-in endpoint (any other endpoint
|
||||||
* other endpoint number).
|
* number).
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0
|
#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0
|
||||||
/*
|
/* Define this to 1 if you want to compile a version with three endpoints: The
|
||||||
* Define this to 1 if you want to compile a version with three endpoints: The default control endpoint 0, an interrupt-in endpoint 3 (or
|
* default control endpoint 0, an interrupt-in endpoint 3 (or the number
|
||||||
* the number configured below) and a catch-all default interrupt-in endpoint as above. You must also define USB_CFG_HAVE_INTRIN_ENDPOINT
|
* configured below) and a catch-all default interrupt-in endpoint as above.
|
||||||
* to 1 for this feature.
|
* You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_EP3_NUMBER 3
|
#define USB_CFG_EP3_NUMBER 3
|
||||||
/*
|
/* If the so-called endpoint 3 is used, it can now be configured to any other
|
||||||
* If the so-called endpoint 3 is used, it can now be configured to any other endpoint number (except 0) with this macro. Default if
|
* endpoint number (except 0) with this macro. Default if undefined is 3.
|
||||||
* undefined is 3.
|
|
||||||
*/
|
*/
|
||||||
/*
|
/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */
|
||||||
* #define USB_INITIAL_DATATOKEN USBPID_DATA1
|
/* The above macro defines the startup condition for data toggling on the
|
||||||
*/
|
* interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1.
|
||||||
/*
|
* Since the token is toggled BEFORE sending any data, the first packet is
|
||||||
* The above macro defines the startup condition for data toggling on the interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1. Since
|
* sent with the oposite value of this configuration!
|
||||||
* the token is toggled BEFORE sending any data, the first packet is sent with the oposite value of this configuration!
|
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_IMPLEMENT_HALT 0
|
#define USB_CFG_IMPLEMENT_HALT 0
|
||||||
/*
|
/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature
|
||||||
* Define this to 1 if you also want to implement the ENDPOINT_HALT feature for endpoint 1 (interrupt endpoint). Although you may not need
|
* for endpoint 1 (interrupt endpoint). Although you may not need this feature,
|
||||||
* this feature, it is required by the standard. We have made it a config option because it bloats the code considerably.
|
* it is required by the standard. We have made it a config option because it
|
||||||
|
* bloats the code considerably.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_SUPPRESS_INTR_CODE 1
|
#define USB_CFG_SUPPRESS_INTR_CODE 1
|
||||||
/*
|
/* Define this to 1 if you want to declare interrupt-in endpoints, but don't
|
||||||
* Define this to 1 if you want to declare interrupt-in endpoints, but don't want to send any data over them. If this macro is defined to
|
* want to send any data over them. If this macro is defined to 1, functions
|
||||||
* 1, functions usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if you need the interrupt-in endpoints in order to
|
* usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if
|
||||||
* comply to an interface (e.g. HID), but never want to send any data. This option saves a couple of bytes in flash memory and the transmit
|
* you need the interrupt-in endpoints in order to comply to an interface
|
||||||
* buffers in RAM.
|
* (e.g. HID), but never want to send any data. This option saves a couple
|
||||||
|
* of bytes in flash memory and the transmit buffers in RAM.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_INTR_POLL_INTERVAL 20
|
#define USB_CFG_INTR_POLL_INTERVAL 200
|
||||||
/*
|
/* If you compile a version with endpoint 1 (interrupt-in), this is the poll
|
||||||
* If you compile a version with endpoint 1 (interrupt-in), this is the poll interval. The value is in milliseconds and must not be less
|
* interval. The value is in milliseconds and must not be less than 10 ms for
|
||||||
* than 10 ms for low speed devices.
|
* low speed devices.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_IS_SELF_POWERED 0
|
#define USB_CFG_IS_SELF_POWERED 0
|
||||||
/*
|
/* Define this to 1 if the device has its own power supply. Set it to 0 if the
|
||||||
* Define this to 1 if the device has its own power supply. Set it to 0 if the device is powered from the USB bus.
|
* device is powered from the USB bus.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_MAX_BUS_POWER 300
|
#define USB_CFG_MAX_BUS_POWER 300
|
||||||
/*
|
/* Set this variable to the maximum USB bus power consumption of your device.
|
||||||
* Set this variable to the maximum USB bus power consumption of your device. The value is in milliamperes. [It will be divided by two
|
* The value is in milliamperes. [It will be divided by two since USB
|
||||||
* since USB communicates power requirements in units of 2 mA.]
|
* communicates power requirements in units of 2 mA.]
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_IMPLEMENT_FN_WRITE 1
|
#define USB_CFG_IMPLEMENT_FN_WRITE 1
|
||||||
/*
|
/* Set this to 1 if you want usbFunctionWrite() to be called for control-out
|
||||||
* Set this to 1 if you want usbFunctionWrite() to be called for control-out transfers. Set it to 0 if you don't need it and want to save a
|
* transfers. Set it to 0 if you don't need it and want to save a couple of
|
||||||
* couple of bytes.
|
* bytes.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_IMPLEMENT_FN_READ 0
|
#define USB_CFG_IMPLEMENT_FN_READ 0
|
||||||
/*
|
/* Set this to 1 if you need to send control replies which are generated
|
||||||
* Set this to 1 if you need to send control replies which are generated "on the fly" when usbFunctionRead() is called. If you only want to
|
* "on the fly" when usbFunctionRead() is called. If you only want to send
|
||||||
* send data from a static buffer, set it to 0 and return the data from usbFunctionSetup(). This saves a couple of bytes.
|
* data from a static buffer, set it to 0 and return the data from
|
||||||
|
* usbFunctionSetup(). This saves a couple of bytes.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0
|
#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0
|
||||||
/*
|
/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints.
|
||||||
* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints. You must implement the function usbFunctionWriteOut() which
|
* You must implement the function usbFunctionWriteOut() which receives all
|
||||||
* receives all interrupt/bulk data sent to any endpoint other than 0. The endpoint number can be found in 'usbRxToken'.
|
* interrupt/bulk data sent to any endpoint other than 0. The endpoint number
|
||||||
|
* can be found in 'usbRxToken'.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_HAVE_FLOWCONTROL 0
|
#define USB_CFG_HAVE_FLOWCONTROL 0
|
||||||
/*
|
/* Define this to 1 if you want flowcontrol over USB data. See the definition
|
||||||
* Define this to 1 if you want flowcontrol over USB data. See the definition of the macros usbDisableAllRequests() and
|
* of the macros usbDisableAllRequests() and usbEnableAllRequests() in
|
||||||
* usbEnableAllRequests() in usbdrv.h.
|
* usbdrv.h.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_LONG_TRANSFERS 0
|
#define USB_CFG_LONG_TRANSFERS 0
|
||||||
/*
|
/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
|
||||||
* Define this to 1 if you want to send/receive blocks of more than 254 bytes in a single control-in or control-out transfer. Note that the
|
* in a single control-in or control-out transfer. Note that the capability
|
||||||
* capability for long transfers increases the driver size.
|
* for long transfers increases the driver size.
|
||||||
*/
|
*/
|
||||||
/*
|
/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */
|
||||||
* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED();
|
/* This macro is a hook if you want to do unconventional things. If it is
|
||||||
|
* defined, it's inserted at the beginning of received message processing.
|
||||||
|
* If you eat the received message and don't want default processing to
|
||||||
|
* proceed, do a return after doing your things. One possible application
|
||||||
|
* (besides debugging) is to flash a status LED on each packet.
|
||||||
*/
|
*/
|
||||||
/*
|
/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */
|
||||||
* This macro is a hook if you want to do unconventional things. If it is defined, it's inserted at the beginning of received message
|
/* This macro is a hook if you need to know when an USB RESET occurs. It has
|
||||||
* processing. If you eat the received message and don't want default processing to proceed, do a return after doing your things. One
|
* one parameter which distinguishes between the start of RESET state and its
|
||||||
* possible application (besides debugging) is to flash a status LED on each packet.
|
* end.
|
||||||
*/
|
*/
|
||||||
/*
|
/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */
|
||||||
* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();}
|
/* This macro (if defined) is executed when a USB SET_ADDRESS request was
|
||||||
*/
|
* received.
|
||||||
/*
|
|
||||||
* This macro is a hook if you need to know when an USB RESET occurs. It has one parameter which distinguishes between the start of RESET
|
|
||||||
* state and its end.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned();
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* This macro (if defined) is executed when a USB SET_ADDRESS request was received.
|
|
||||||
*/
|
*/
|
||||||
#define USB_COUNT_SOF 0
|
#define USB_COUNT_SOF 0
|
||||||
/*
|
/* define this macro to 1 if you need the global variable "usbSofCount" which
|
||||||
* define this macro to 1 if you need the global variable "usbSofCount" which counts SOF packets. This feature requires that the hardware
|
* counts SOF packets. This feature requires that the hardware interrupt is
|
||||||
* interrupt is connected to D- instead of D+.
|
* connected to D- instead of D+.
|
||||||
*/
|
*/
|
||||||
/*
|
/* #ifdef __ASSEMBLER__
|
||||||
* #ifdef __ASSEMBLER__ macro myAssemblerMacro in YL, TCNT0 sts timer0Snapshot, YL endm #endif #define USB_SOF_HOOK myAssemblerMacro This
|
* macro myAssemblerMacro
|
||||||
* macro (if defined) is executed in the assembler module when a Start Of Frame condition is detected. It is recommended to define it to
|
* in YL, TCNT0
|
||||||
* the name of an assembler macro which is defined here as well so that more than one assembler instruction can be used. The macro may use
|
* sts timer0Snapshot, YL
|
||||||
* the register YL and modify SREG. If it lasts longer than a couple of cycles, USB messages immediately after an SOF pulse may be lost and
|
* endm
|
||||||
* must be retried by the host. What can you do with this hook? Since the SOF signal occurs exactly every 1 ms (unless the host is in sleep
|
* #endif
|
||||||
* mode), you can use it to tune OSCCAL in designs running on the internal RC oscillator. Please note that Start Of Frame detection works
|
* #define USB_SOF_HOOK myAssemblerMacro
|
||||||
* only if D- is wired to the interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
|
* This macro (if defined) is executed in the assembler module when a
|
||||||
|
* Start Of Frame condition is detected. It is recommended to define it to
|
||||||
|
* the name of an assembler macro which is defined here as well so that more
|
||||||
|
* than one assembler instruction can be used. The macro may use the register
|
||||||
|
* YL and modify SREG. If it lasts longer than a couple of cycles, USB messages
|
||||||
|
* immediately after an SOF pulse may be lost and must be retried by the host.
|
||||||
|
* What can you do with this hook? Since the SOF signal occurs exactly every
|
||||||
|
* 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in
|
||||||
|
* designs running on the internal RC oscillator.
|
||||||
|
* Please note that Start Of Frame detection works only if D- is wired to the
|
||||||
|
* interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_CHECK_DATA_TOGGLING 0
|
#define USB_CFG_CHECK_DATA_TOGGLING 0
|
||||||
/*
|
/* define this macro to 1 if you want to filter out duplicate data packets
|
||||||
* define this macro to 1 if you want to filter out duplicate data packets sent by the host. Duplicates occur only as a consequence of
|
* sent by the host. Duplicates occur only as a consequence of communication
|
||||||
* communication errors, when the host does not receive an ACK. Please note that you need to implement the filtering yourself in
|
* errors, when the host does not receive an ACK. Please note that you need to
|
||||||
* usbFunctionWriteOut() and usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable for each control- and
|
* implement the filtering yourself in usbFunctionWriteOut() and
|
||||||
* out-endpoint to check for duplicate packets.
|
* usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
|
||||||
|
* for each control- and out-endpoint to check for duplicate packets.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
|
#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
|
||||||
/*
|
/* define this macro to 1 if you want the function usbMeasureFrameLength()
|
||||||
* define this macro to 1 if you want the function usbMeasureFrameLength() compiled in. This function can be used to calibrate the AVR's RC
|
* compiled in. This function can be used to calibrate the AVR's RC oscillator.
|
||||||
* oscillator.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/* -------------------------- Device Description --------------------------- */
|
||||||
* -------------------------- Device Description ---------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define USB_CFG_VENDOR_ID 0xc0, 0x16
|
#define USB_CFG_VENDOR_ID 0xc0, 0x16
|
||||||
/*
|
/* USB vendor ID for the device, low byte first. If you have registered your
|
||||||
* USB vendor ID for the device, low byte first. If you have registered your own Vendor ID, define it here. Otherwise you use one of
|
* own Vendor ID, define it here. Otherwise you use one of obdev's free shared
|
||||||
* obdev's free shared VID/PID pairs. Be sure to read USBID-License.txt for rules!
|
* VID/PID pairs. Be sure to read USBID-License.txt for rules!
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DEVICE_ID 0xdd, 0x05
|
#define USB_CFG_DEVICE_ID 0xdd, 0x05
|
||||||
/*
|
/* This is the ID of the product, low byte first. It is interpreted in the
|
||||||
* This is the ID of the product, low byte first. It is interpreted in the scope of the vendor ID. If you have registered your own VID with
|
* scope of the vendor ID. If you have registered your own VID with usb.org
|
||||||
* usb.org or if you have licensed a PID from somebody else, define it here. Otherwise you use obdev's free shared VID/PID pair. Be sure to
|
* or if you have licensed a PID from somebody else, define it here. Otherwise
|
||||||
* read the rules in USBID-License.txt!
|
* you use obdev's free shared VID/PID pair. Be sure to read the rules in
|
||||||
|
* USBID-License.txt!
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DEVICE_VERSION 0x00, 0x01
|
#define USB_CFG_DEVICE_VERSION 0x00, 0x01
|
||||||
/*
|
/* Version number of the device: Minor number first, then major number.
|
||||||
* Version number of the device: Minor number first, then major number.
|
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_VENDOR_NAME 'o', 'p', 't', 'i', 'x', 'x', '.', 'o', 'r', 'g'
|
#define USB_CFG_VENDOR_NAME 'o', 'p', 't', 'i', 'x', 'x', '.', 'o', 'r', 'g'
|
||||||
#define USB_CFG_VENDOR_NAME_LEN 10
|
#define USB_CFG_VENDOR_NAME_LEN 10
|
||||||
/*
|
/* These two values define the vendor name returned by the USB device. The name
|
||||||
* These two values define the vendor name returned by the USB device. The name must be given as a list of characters under single quotes.
|
* must be given as a list of characters under single quotes. The characters
|
||||||
* The characters are interpreted as Unicode (UTF-16) entities. If you don't want a vendor name string, undefine these macros. ALWAYS
|
* are interpreted as Unicode (UTF-16) entities.
|
||||||
* define a vendor name containing your Internet domain name if you use obdev's free shared VID/PID pair. See the file USBID-License.txt
|
* If you don't want a vendor name string, undefine these macros.
|
||||||
* for details.
|
* ALWAYS define a vendor name containing your Internet domain name if you use
|
||||||
|
* obdev's free shared VID/PID pair. See the file USBID-License.txt for
|
||||||
|
* details.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DEVICE_NAME 'Q', 'U', 'I', 'C', 'K', 'D', 'E', 'V', '1', '6'
|
#define USB_CFG_DEVICE_NAME 'Q', 'U', 'I', 'C', 'K', 'D', 'E', 'V', '1', '6'
|
||||||
#define USB_CFG_DEVICE_NAME_LEN 10
|
#define USB_CFG_DEVICE_NAME_LEN 10
|
||||||
/*
|
/* Same as above for the device name. If you don't want a device name, undefine
|
||||||
* Same as above for the device name. If you don't want a device name, undefine the macros. See the file USBID-License.txt before you
|
* the macros. See the file USBID-License.txt before you assign a name if you
|
||||||
* assign a name if you use a shared VID/PID.
|
* use a shared VID/PID.
|
||||||
*/
|
*/
|
||||||
/*
|
/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */
|
||||||
* #define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e'
|
/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */
|
||||||
*/
|
/* Same as above for the serial number. If you don't want a serial number,
|
||||||
/*
|
* undefine the macros.
|
||||||
* #define USB_CFG_SERIAL_NUMBER_LEN 0
|
* It may be useful to provide the serial number through other means than at
|
||||||
*/
|
* compile time. See the section about descriptor properties below for how
|
||||||
/*
|
* to fine tune control over USB descriptors such as the string descriptor
|
||||||
* Same as above for the serial number. If you don't want a serial number, undefine the macros. It may be useful to provide the serial
|
* for the serial number.
|
||||||
* number through other means than at compile time. See the section about descriptor properties below for how to fine tune control over USB
|
|
||||||
* descriptors such as the string descriptor for the serial number.
|
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DEVICE_CLASS 0xff /* set to 0 if deferred to interface */
|
#define USB_CFG_DEVICE_CLASS 0xff /* set to 0 if deferred to interface */
|
||||||
#define USB_CFG_DEVICE_SUBCLASS 0
|
#define USB_CFG_DEVICE_SUBCLASS 0
|
||||||
/*
|
/* See USB specification if you want to conform to an existing device class.
|
||||||
* See USB specification if you want to conform to an existing device class. Class 0xff is "vendor specific".
|
* Class 0xff is "vendor specific".
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_INTERFACE_CLASS 0 /* define class here if not at device level */
|
#define USB_CFG_INTERFACE_CLASS 0 /* define class here if not at device level */
|
||||||
#define USB_CFG_INTERFACE_SUBCLASS 0
|
#define USB_CFG_INTERFACE_SUBCLASS 0
|
||||||
#define USB_CFG_INTERFACE_PROTOCOL 0
|
#define USB_CFG_INTERFACE_PROTOCOL 0
|
||||||
/*
|
/* See USB specification if you want to conform to an existing device class or
|
||||||
* See USB specification if you want to conform to an existing device class or protocol. The following classes must be set at interface
|
* protocol. The following classes must be set at interface level:
|
||||||
* level: HID class is 3, no subclass and protocol required (but may be useful!) CDC class is 2, use subclass 2 and protocol 1 for ACM
|
* HID class is 3, no subclass and protocol required (but may be useful!)
|
||||||
|
* CDC class is 2, use subclass 2 and protocol 1 for ACM
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 0
|
#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 0
|
||||||
|
|
||||||
/*
|
/* Define this to the length of the HID report descriptor, if you implement
|
||||||
* Define this to the length of the HID report descriptor, if you implement an HID device. Otherwise don't define it or define it to 0. If
|
* an HID device. Otherwise don't define it or define it to 0.
|
||||||
* you use this define, you must add a PROGMEM character array named "usbHidReportDescriptor" to your code which contains the report
|
* If you use this define, you must add a PROGMEM character array named
|
||||||
* descriptor. Don't forget to keep the array and this define in sync!
|
* "usbHidReportDescriptor" to your code which contains the report descriptor.
|
||||||
|
* Don't forget to keep the array and this define in sync!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/* #define USB_PUBLIC static */
|
||||||
* #define USB_PUBLIC static
|
/* Use the define above if you #include usbdrv.c instead of linking against it.
|
||||||
*/
|
* This technique saves a couple of bytes in flash memory.
|
||||||
/*
|
|
||||||
* Use the define above if you #include usbdrv.c instead of linking against it. This technique saves a couple of bytes in flash memory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/* ------------------- Fine Control over USB Descriptors ------------------- */
|
||||||
* ------------------- Fine Control over USB Descriptors -------------------
|
/* If you don't want to use the driver's default USB descriptors, you can
|
||||||
*/
|
* provide our own. These can be provided as (1) fixed length static data in
|
||||||
/*
|
* flash memory, (2) fixed length static data in RAM or (3) dynamically at
|
||||||
* If you don't want to use the driver's default USB descriptors, you can provide our own. These can be provided as (1) fixed length static
|
* runtime in the function usbFunctionDescriptor(). See usbdrv.h for more
|
||||||
* data in flash memory, (2) fixed length static data in RAM or (3) dynamically at runtime in the function usbFunctionDescriptor(). See
|
* information about this function.
|
||||||
* usbdrv.h for more information about this function. Descriptor handling is configured through the descriptor's properties. If no
|
* Descriptor handling is configured through the descriptor's properties. If
|
||||||
* properties are defined or if they are 0, the default descriptor is used. Possible properties are: + USB_PROP_IS_DYNAMIC: The data for
|
* no properties are defined or if they are 0, the default descriptor is used.
|
||||||
* the descriptor should be fetched at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is used, the data is in FLASH by
|
* Possible properties are:
|
||||||
* default. Add property USB_PROP_IS_RAM if you want RAM pointers. + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or
|
* + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
|
||||||
* found in static memory is in RAM, not in flash memory. + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash), the
|
* at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is
|
||||||
* driver must know the descriptor's length. The descriptor itself is found at the address of a well known identifier (see below). List of
|
* used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if
|
||||||
* static descriptor names (must be declared PROGMEM if in flash): char usbDescriptorDevice[]; char usbDescriptorConfiguration[]; char
|
* you want RAM pointers.
|
||||||
* usbDescriptorHidReport[]; char usbDescriptorString0[]; int usbDescriptorStringVendor[]; int usbDescriptorStringDevice[]; int
|
* + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
|
||||||
* usbDescriptorStringSerialNumber[]; Other descriptors can't be provided statically, they must be provided dynamically at runtime.
|
* in static memory is in RAM, not in flash memory.
|
||||||
* Descriptor properties are or-ed or added together, e.g.: #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18)) The
|
* + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
|
||||||
* following descriptors are defined: USB_CFG_DESCR_PROPS_DEVICE USB_CFG_DESCR_PROPS_CONFIGURATION USB_CFG_DESCR_PROPS_STRINGS
|
* the driver must know the descriptor's length. The descriptor itself is
|
||||||
* USB_CFG_DESCR_PROPS_STRING_0 USB_CFG_DESCR_PROPS_STRING_VENDOR USB_CFG_DESCR_PROPS_STRING_PRODUCT
|
* found at the address of a well known identifier (see below).
|
||||||
* USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER USB_CFG_DESCR_PROPS_HID USB_CFG_DESCR_PROPS_HID_REPORT USB_CFG_DESCR_PROPS_UNKNOWN (for all
|
* List of static descriptor names (must be declared PROGMEM if in flash):
|
||||||
* descriptors not handled by the driver) Note about string descriptors: String descriptors are not just strings, they are Unicode strings
|
* char usbDescriptorDevice[];
|
||||||
* prefixed with a 2 byte header. Example: int serialNumberDescriptor[] = { USB_STRING_DESCRIPTOR_HEADER(6), 'S', 'e', 'r', 'i', 'a', 'l'
|
* char usbDescriptorConfiguration[];
|
||||||
|
* char usbDescriptorHidReport[];
|
||||||
|
* char usbDescriptorString0[];
|
||||||
|
* int usbDescriptorStringVendor[];
|
||||||
|
* int usbDescriptorStringDevice[];
|
||||||
|
* int usbDescriptorStringSerialNumber[];
|
||||||
|
* Other descriptors can't be provided statically, they must be provided
|
||||||
|
* dynamically at runtime.
|
||||||
|
*
|
||||||
|
* Descriptor properties are or-ed or added together, e.g.:
|
||||||
|
* #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18))
|
||||||
|
*
|
||||||
|
* The following descriptors are defined:
|
||||||
|
* USB_CFG_DESCR_PROPS_DEVICE
|
||||||
|
* USB_CFG_DESCR_PROPS_CONFIGURATION
|
||||||
|
* USB_CFG_DESCR_PROPS_STRINGS
|
||||||
|
* USB_CFG_DESCR_PROPS_STRING_0
|
||||||
|
* USB_CFG_DESCR_PROPS_STRING_VENDOR
|
||||||
|
* USB_CFG_DESCR_PROPS_STRING_PRODUCT
|
||||||
|
* USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
|
||||||
|
* USB_CFG_DESCR_PROPS_HID
|
||||||
|
* USB_CFG_DESCR_PROPS_HID_REPORT
|
||||||
|
* USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
|
||||||
|
*
|
||||||
|
* Note about string descriptors: String descriptors are not just strings, they
|
||||||
|
* are Unicode strings prefixed with a 2 byte header. Example:
|
||||||
|
* int serialNumberDescriptor[] = {
|
||||||
|
* USB_STRING_DESCRIPTOR_HEADER(6),
|
||||||
|
* 'S', 'e', 'r', 'i', 'a', 'l'
|
||||||
* };
|
* };
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -315,38 +353,21 @@
|
|||||||
#define USB_CFG_DESCR_PROPS_HID_REPORT 0
|
#define USB_CFG_DESCR_PROPS_HID_REPORT 0
|
||||||
#define USB_CFG_DESCR_PROPS_UNKNOWN 0
|
#define USB_CFG_DESCR_PROPS_UNKNOWN 0
|
||||||
|
|
||||||
/*
|
/* ----------------------- Optional MCU Description ------------------------ */
|
||||||
* ----------------------- Optional MCU Description ------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/* The following configurations have working defaults in usbdrv.h. You
|
||||||
* The following configurations have working defaults in usbdrv.h. You usually don't need to set them explicitly. Only if you want to run
|
* usually don't need to set them explicitly. Only if you want to run
|
||||||
* the driver on a device which is not yet supported or with a compiler which is not fully supported (such as IAR C) or if you use a
|
* the driver on a device which is not yet supported or with a compiler
|
||||||
* differnt interrupt than INT0, you may have to define some of these.
|
* which is not fully supported (such as IAR C) or if you use a differnt
|
||||||
*/
|
* interrupt than INT0, you may have to define some of these.
|
||||||
/*
|
|
||||||
* #define USB_INTR_CFG MCUCR
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01))
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* #define USB_INTR_CFG_CLR 0
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* #define USB_INTR_ENABLE GIMSK
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* #define USB_INTR_ENABLE_BIT INT0
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* #define USB_INTR_PENDING GIFR
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* #define USB_INTR_PENDING_BIT INTF0
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* #define USB_INTR_VECTOR SIG_INTERRUPT0
|
|
||||||
*/
|
*/
|
||||||
|
/* #define USB_INTR_CFG MCUCR */
|
||||||
|
/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */
|
||||||
|
/* #define USB_INTR_CFG_CLR 0 */
|
||||||
|
/* #define USB_INTR_ENABLE GIMSK */
|
||||||
|
/* #define USB_INTR_ENABLE_BIT INT0 */
|
||||||
|
/* #define USB_INTR_PENDING GIFR */
|
||||||
|
/* #define USB_INTR_PENDING_BIT INTF0 */
|
||||||
|
/* #define USB_INTR_VECTOR SIG_INTERRUPT0 */
|
||||||
|
|
||||||
#endif /* __usbconfig_h_included__ */
|
#endif /* __usbconfig_h_included__ */
|
||||||
|
|||||||
@ -275,55 +275,3 @@ Scroll down to the bottom to see the most recent changes.
|
|||||||
background of USB ID registration clearer.
|
background of USB ID registration clearer.
|
||||||
|
|
||||||
* Release 2009-04-15
|
* Release 2009-04-15
|
||||||
|
|
||||||
- Changed CommercialLicense.txt to reflect the new range of PIDs from
|
|
||||||
Jason Kotzin.
|
|
||||||
- Removed USBID-License.txt in favor of USB-IDs-for-free.txt and
|
|
||||||
USB-ID-FAQ.txt
|
|
||||||
- Fixed a bug in the 12.8 MHz module: End Of Packet decection was made in
|
|
||||||
the center between bit 0 and 1 of each byte. This is where the data lines
|
|
||||||
are expected to change and the sampled data may therefore be nonsense.
|
|
||||||
We therefore check EOP ONLY if bits 0 AND 1 have both been read as 0 on D-.
|
|
||||||
- Fixed a bitstuffing problem in the 16 MHz module: If bit 6 was stuffed,
|
|
||||||
the unstuffing code in the receiver routine was 1 cycle too long. If
|
|
||||||
multiple bytes had the unstuffing in bit 6, the error summed up until the
|
|
||||||
receiver was out of sync.
|
|
||||||
- Included option for faster CRC routine.
|
|
||||||
Thanks to Slawomir Fras (BoskiDialer) for this code!
|
|
||||||
- Updated bits in Configuration Descriptor's bmAttributes according to
|
|
||||||
USB 1.1 (in particular bit 7, it is a must-be-set bit now).
|
|
||||||
|
|
||||||
* Release 2009-08-22
|
|
||||||
|
|
||||||
- Moved first DBG1() after odDebugInit() in all examples.
|
|
||||||
- Use vector INT0_vect instead of SIG_INTERRUPT0 if defined. This makes
|
|
||||||
V-USB compatible with the new "p" suffix devices (e.g. ATMega328p).
|
|
||||||
- USB_CFG_CLOCK_KHZ setting is now required in usbconfig.h (no default any
|
|
||||||
more).
|
|
||||||
- New option USB_CFG_DRIVER_FLASH_PAGE allows boot loaders on devices with
|
|
||||||
more than 64 kB flash.
|
|
||||||
- Built-in configuration descriptor allows custom definition for second
|
|
||||||
endpoint now.
|
|
||||||
|
|
||||||
* Release 2010-07-15
|
|
||||||
|
|
||||||
- Fixed bug in usbDriverSetup() which prevented descriptor sizes above 255
|
|
||||||
bytes.
|
|
||||||
- Avoid a compiler warning for unused parameter in usbHandleResetHook() when
|
|
||||||
compiler option -Wextra is enabled.
|
|
||||||
- Fixed wrong hex value for some IDs in USB-IDs-for-free.txt.
|
|
||||||
- Keep a define for USBATTR_BUSPOWER, although the flag does not exist
|
|
||||||
in USB 1.1 any more. Set it to 0. This is for backward compatibility.
|
|
||||||
|
|
||||||
* Release 2012-01-09
|
|
||||||
|
|
||||||
- Define a separate (defined) type for usbMsgPtr so that projects using a
|
|
||||||
tiny memory model can define it to an 8 bit type in usbconfig.h. This
|
|
||||||
change also saves a couple of bytes when using a scalar 16 bit type.
|
|
||||||
- Inserted "const" keyword for all PROGMEM declarations because new GCC
|
|
||||||
requires it.
|
|
||||||
- Fixed problem with dependence of usbportability.h on usbconfig.h. This
|
|
||||||
problem occurred with IAR CC only.
|
|
||||||
- Prepared repository for github.com.
|
|
||||||
|
|
||||||
* Release 2012-12-06
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
V-USB Driver Software License Agreement
|
V-USB Driver Software License Agreement
|
||||||
Version 2012-07-09
|
Version 2009-04-14
|
||||||
|
|
||||||
THIS LICENSE AGREEMENT GRANTS YOU CERTAIN RIGHTS IN A SOFTWARE. YOU CAN
|
THIS LICENSE AGREEMENT GRANTS YOU CERTAIN RIGHTS IN A SOFTWARE. YOU CAN
|
||||||
ENTER INTO THIS AGREEMENT AND ACQUIRE THE RIGHTS OUTLINED BELOW BY PAYING
|
ENTER INTO THIS AGREEMENT AND ACQUIRE THE RIGHTS OUTLINED BELOW BY PAYING
|
||||||
@ -32,22 +32,13 @@ product(s), restricted by the limitations in section 3 below.
|
|||||||
2.3 Modifications. OBJECTIVE DEVELOPMENT grants you the right to modify
|
2.3 Modifications. OBJECTIVE DEVELOPMENT grants you the right to modify
|
||||||
the source code and your copy of V-USB according to your needs.
|
the source code and your copy of V-USB according to your needs.
|
||||||
|
|
||||||
2.4 USB IDs. OBJECTIVE DEVELOPMENT furnishes you with one or two USB
|
2.4 USB IDs. OBJECTIVE DEVELOPMENT furnishes you with one or two USB Product
|
||||||
Product ID(s), sent to you in e-mail. These Product IDs are reserved
|
ID(s), sent to you in e-mail. These Product IDs are reserved exclusively for
|
||||||
exclusively for you. OBJECTIVE DEVELOPMENT has obtained USB Product ID
|
you. They have been obtained from Wouter van Ooijen (www.voti.nl), who has
|
||||||
ranges under the Vendor ID 5824 from Wouter van Ooijen (Van Ooijen
|
reserved the Vendor ID 5824 (decimal) at the USB Implementers Forum, Inc.
|
||||||
Technische Informatica, www.voti.nl) and under the Vendor ID 8352 from
|
(www.usb.org). This mechanism ensures that there are no Product ID conflicts,
|
||||||
Jason Kotzin (now flirc.tv, Inc.). Both owners of the Vendor IDs have
|
but you cannot become USB certified (enter into the USB-IF Trademark License
|
||||||
obtained these IDs from the USB Implementers Forum, Inc. (www.usb.org).
|
Agreement) as you would need your own Vendor ID for that.
|
||||||
OBJECTIVE DEVELOPMENT disclaims all liability which might arise from the
|
|
||||||
assignment of USB IDs.
|
|
||||||
|
|
||||||
2.5 USB Certification. Although not part of this agreement, we want to make
|
|
||||||
it clear that you cannot become USB certified when you use V-USB or a USB
|
|
||||||
Product ID assigned by OBJECTIVE DEVELOPMENT. AVR microcontrollers don't
|
|
||||||
meet the electrical specifications required by the USB specification and
|
|
||||||
the USB Implementers Forum certifies only members who bought a Vendor ID of
|
|
||||||
their own.
|
|
||||||
|
|
||||||
|
|
||||||
3 LICENSE RESTRICTIONS
|
3 LICENSE RESTRICTIONS
|
||||||
|
|||||||
@ -39,8 +39,8 @@ The driver consists of the following files:
|
|||||||
with IAR's tools.
|
with IAR's tools.
|
||||||
License.txt ............ Open Source license for this driver.
|
License.txt ............ Open Source license for this driver.
|
||||||
CommercialLicense.txt .. Optional commercial license for this driver.
|
CommercialLicense.txt .. Optional commercial license for this driver.
|
||||||
USB-ID-FAQ.txt ......... General infos about USB Product- and Vendor-IDs.
|
USBID-License.txt ...... Terms and conditions for using particular USB ID
|
||||||
USB-IDs-for-free.txt ... List and terms of use for free shared PIDs.
|
values for particular purposes.
|
||||||
|
|
||||||
(*) ... These files should be linked to your project.
|
(*) ... These files should be linked to your project.
|
||||||
|
|
||||||
@ -49,7 +49,8 @@ CPU CORE CLOCK FREQUENCY
|
|||||||
========================
|
========================
|
||||||
We supply assembler modules for clock frequencies of 12 MHz, 12.8 MHz, 15 MHz,
|
We supply assembler modules for clock frequencies of 12 MHz, 12.8 MHz, 15 MHz,
|
||||||
16 MHz, 16.5 MHz 18 MHz and 20 MHz. Other clock rates are not supported. The
|
16 MHz, 16.5 MHz 18 MHz and 20 MHz. Other clock rates are not supported. The
|
||||||
actual clock rate must be configured in usbconfig.h.
|
actual clock rate must be configured in usbdrv.h unless you use the default
|
||||||
|
12 MHz.
|
||||||
|
|
||||||
12 MHz Clock
|
12 MHz Clock
|
||||||
This is the traditional clock rate of V-USB because it's the lowest clock
|
This is the traditional clock rate of V-USB because it's the lowest clock
|
||||||
@ -104,7 +105,7 @@ can assign PIDs at will.
|
|||||||
|
|
||||||
Since an entry level cost of 1,500 USD is too high for most small companies
|
Since an entry level cost of 1,500 USD is too high for most small companies
|
||||||
and hobbyists, we provide some VID/PID pairs for free. See the file
|
and hobbyists, we provide some VID/PID pairs for free. See the file
|
||||||
USB-IDs-for-free.txt for details.
|
USBID-License.txt for details.
|
||||||
|
|
||||||
Objective Development also has some license offerings which include product
|
Objective Development also has some license offerings which include product
|
||||||
IDs. See http://www.obdev.at/vusb/ for details.
|
IDs. See http://www.obdev.at/vusb/ for details.
|
||||||
@ -113,28 +114,13 @@ IDs. See http://www.obdev.at/vusb/ for details.
|
|||||||
DEVELOPMENT SYSTEM
|
DEVELOPMENT SYSTEM
|
||||||
==================
|
==================
|
||||||
This driver has been developed and optimized for the GNU compiler version 3
|
This driver has been developed and optimized for the GNU compiler version 3
|
||||||
and 4. We recommend that you use the GNU compiler suite because it is freely
|
(gcc 3). It does work well with gcc 4, but with bigger code size. We recommend
|
||||||
available. V-USB has also been ported to the IAR compiler and assembler. It
|
that you use the GNU compiler suite because it is freely available. V-USB
|
||||||
has been tested with IAR 4.10B/W32 and 4.12A/W32 on an ATmega8 with the
|
has also been ported to the IAR compiler and assembler. It has been tested
|
||||||
"small" and "tiny" memory model. Not every release is tested with IAR CC and
|
with IAR 4.10B/W32 and 4.12A/W32 on an ATmega8 with the "small" and "tiny"
|
||||||
the driver may therefore fail to compile with IAR. Please note that gcc is
|
memory model. Not every release is tested with IAR CC and the driver may
|
||||||
more efficient for usbdrv.c because this module has been deliberately
|
therefore fail to compile with IAR. Please note that gcc is more efficient for
|
||||||
optimized for gcc.
|
usbdrv.c because this module has been deliberately optimized for gcc.
|
||||||
|
|
||||||
Gcc version 3 produces smaller code than version 4 due to new optimizing
|
|
||||||
capabilities which don't always improve things on 8 bit CPUs. The code size
|
|
||||||
generated by gcc 4 can be reduced with the compiler options
|
|
||||||
-fno-move-loop-invariants, -fno-tree-scev-cprop and
|
|
||||||
-fno-inline-small-functions in addition to -Os. On devices with more than
|
|
||||||
8k of flash memory, we also recommend the linker option --relax (written as
|
|
||||||
-Wl,--relax for gcc) to convert absolute calls into relative where possible.
|
|
||||||
|
|
||||||
For more information about optimizing options see:
|
|
||||||
|
|
||||||
http://www.tty1.net/blog/2008-04-29-avr-gcc-optimisations_en.html
|
|
||||||
|
|
||||||
These optimizations are good for gcc 4.x. Version 3.x of gcc does not support
|
|
||||||
most of these options and produces good code anyway.
|
|
||||||
|
|
||||||
|
|
||||||
USING V-USB FOR FREE
|
USING V-USB FOR FREE
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* Revision: $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: oddebug.c 692 2008-11-07 15:07:40Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "oddebug.h"
|
#include "oddebug.h"
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: oddebug.h 692 2008-11-07 15:07:40Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __oddebug_h_included__
|
#ifndef __oddebug_h_included__
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: usbconfig-prototype.h 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __usbconfig_h_included__
|
#ifndef __usbconfig_h_included__
|
||||||
@ -44,12 +45,10 @@ section at the end of this file).
|
|||||||
*/
|
*/
|
||||||
#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
|
#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
|
||||||
/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000,
|
/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000,
|
||||||
* 16500, 18000 and 20000. The 12.8 MHz and 16.5 MHz versions of the code
|
* 16500 and 20000. The 12.8 MHz and 16.5 MHz versions of the code require no
|
||||||
* require no crystal, they tolerate +/- 1% deviation from the nominal
|
* crystal, they tolerate +/- 1% deviation from the nominal frequency. All
|
||||||
* frequency. All other rates require a precision of 2000 ppm and thus a
|
* other rates require a precision of 2000 ppm and thus a crystal!
|
||||||
* crystal!
|
* Default if not specified: 12 MHz
|
||||||
* Since F_CPU should be defined to your actual clock rate anyway, you should
|
|
||||||
* not need to modify this setting.
|
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_CHECK_CRC 0
|
#define USB_CFG_CHECK_CRC 0
|
||||||
/* Define this to 1 if you want that the driver checks integrity of incoming
|
/* Define this to 1 if you want that the driver checks integrity of incoming
|
||||||
@ -145,11 +144,6 @@ section at the end of this file).
|
|||||||
* of the macros usbDisableAllRequests() and usbEnableAllRequests() in
|
* of the macros usbDisableAllRequests() and usbEnableAllRequests() in
|
||||||
* usbdrv.h.
|
* usbdrv.h.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DRIVER_FLASH_PAGE 0
|
|
||||||
/* If the device has more than 64 kBytes of flash, define this to the 64 k page
|
|
||||||
* where the driver's constants (descriptors) are located. Or in other words:
|
|
||||||
* Define this to 1 for boot loaders on the ATMega128.
|
|
||||||
*/
|
|
||||||
#define USB_CFG_LONG_TRANSFERS 0
|
#define USB_CFG_LONG_TRANSFERS 0
|
||||||
/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
|
/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
|
||||||
* in a single control-in or control-out transfer. Note that the capability
|
* in a single control-in or control-out transfer. Note that the capability
|
||||||
@ -207,36 +201,24 @@ section at the end of this file).
|
|||||||
/* define this macro to 1 if you want the function usbMeasureFrameLength()
|
/* define this macro to 1 if you want the function usbMeasureFrameLength()
|
||||||
* compiled in. This function can be used to calibrate the AVR's RC oscillator.
|
* compiled in. This function can be used to calibrate the AVR's RC oscillator.
|
||||||
*/
|
*/
|
||||||
#define USB_USE_FAST_CRC 0
|
|
||||||
/* The assembler module has two implementations for the CRC algorithm. One is
|
|
||||||
* faster, the other is smaller. This CRC routine is only used for transmitted
|
|
||||||
* messages where timing is not critical. The faster routine needs 31 cycles
|
|
||||||
* per byte while the smaller one needs 61 to 69 cycles. The faster routine
|
|
||||||
* may be worth the 32 bytes bigger code size if you transmit lots of data and
|
|
||||||
* run the AVR close to its limit.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* -------------------------- Device Description --------------------------- */
|
/* -------------------------- Device Description --------------------------- */
|
||||||
|
|
||||||
#define USB_CFG_VENDOR_ID 0xc0, 0x16 /* = 0x16c0 = 5824 = voti.nl */
|
#define USB_CFG_VENDOR_ID 0xc0, 0x16
|
||||||
/* USB vendor ID for the device, low byte first. If you have registered your
|
/* USB vendor ID for the device, low byte first. If you have registered your
|
||||||
* own Vendor ID, define it here. Otherwise you may use one of obdev's free
|
* own Vendor ID, define it here. Otherwise you use one of obdev's free shared
|
||||||
* shared VID/PID pairs. Be sure to read USB-IDs-for-free.txt for rules!
|
* VID/PID pairs. Be sure to read USBID-License.txt for rules!
|
||||||
* *** IMPORTANT NOTE ***
|
* + This template uses obdev's shared VID/PID pair: 0x16c0/0x5dc.
|
||||||
* This template uses obdev's shared VID/PID pair for Vendor Class devices
|
* + Use this VID/PID pair ONLY if you understand the implications!
|
||||||
* with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
|
|
||||||
* the implications!
|
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DEVICE_ID 0xdc, 0x05 /* = 0x05dc = 1500 */
|
#define USB_CFG_DEVICE_ID 0xdc, 0x05
|
||||||
/* This is the ID of the product, low byte first. It is interpreted in the
|
/* This is the ID of the product, low byte first. It is interpreted in the
|
||||||
* scope of the vendor ID. If you have registered your own VID with usb.org
|
* scope of the vendor ID. If you have registered your own VID with usb.org
|
||||||
* or if you have licensed a PID from somebody else, define it here. Otherwise
|
* or if you have licensed a PID from somebody else, define it here. Otherwise
|
||||||
* you may use one of obdev's free shared VID/PID pairs. See the file
|
* you use obdev's free shared VID/PID pair. Be sure to read the rules in
|
||||||
* USB-IDs-for-free.txt for details!
|
* USBID-License.txt!
|
||||||
* *** IMPORTANT NOTE ***
|
* + This template uses obdev's shared VID/PID pair: 0x16c0/0x5dc.
|
||||||
* This template uses obdev's shared VID/PID pair for Vendor Class devices
|
* + Use this VID/PID pair ONLY if you understand the implications!
|
||||||
* with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
|
|
||||||
* the implications!
|
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DEVICE_VERSION 0x00, 0x01
|
#define USB_CFG_DEVICE_VERSION 0x00, 0x01
|
||||||
/* Version number of the device: Minor number first, then major number.
|
/* Version number of the device: Minor number first, then major number.
|
||||||
@ -248,14 +230,14 @@ section at the end of this file).
|
|||||||
* are interpreted as Unicode (UTF-16) entities.
|
* are interpreted as Unicode (UTF-16) entities.
|
||||||
* If you don't want a vendor name string, undefine these macros.
|
* If you don't want a vendor name string, undefine these macros.
|
||||||
* ALWAYS define a vendor name containing your Internet domain name if you use
|
* ALWAYS define a vendor name containing your Internet domain name if you use
|
||||||
* obdev's free shared VID/PID pair. See the file USB-IDs-for-free.txt for
|
* obdev's free shared VID/PID pair. See the file USBID-License.txt for
|
||||||
* details.
|
* details.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DEVICE_NAME 'T', 'e', 'm', 'p', 'l', 'a', 't', 'e'
|
#define USB_CFG_DEVICE_NAME 'T', 'e', 'm', 'p', 'l', 'a', 't', 'e'
|
||||||
#define USB_CFG_DEVICE_NAME_LEN 8
|
#define USB_CFG_DEVICE_NAME_LEN 8
|
||||||
/* Same as above for the device name. If you don't want a device name, undefine
|
/* Same as above for the device name. If you don't want a device name, undefine
|
||||||
* the macros. See the file USB-IDs-for-free.txt before you assign a name if
|
* the macros. See the file USBID-License.txt before you assign a name if you
|
||||||
* you use a shared VID/PID.
|
* use a shared VID/PID.
|
||||||
*/
|
*/
|
||||||
/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */
|
/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */
|
||||||
/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */
|
/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */
|
||||||
@ -355,15 +337,6 @@ section at the end of this file).
|
|||||||
#define USB_CFG_DESCR_PROPS_HID_REPORT 0
|
#define USB_CFG_DESCR_PROPS_HID_REPORT 0
|
||||||
#define USB_CFG_DESCR_PROPS_UNKNOWN 0
|
#define USB_CFG_DESCR_PROPS_UNKNOWN 0
|
||||||
|
|
||||||
|
|
||||||
#define usbMsgPtr_t unsigned short
|
|
||||||
/* If usbMsgPtr_t is not defined, it defaults to 'uchar *'. We define it to
|
|
||||||
* a scalar type here because gcc generates slightly shorter code for scalar
|
|
||||||
* arithmetics than for pointer arithmetics. Remove this define for backward
|
|
||||||
* type compatibility or define it to an 8 bit type if you use data in RAM only
|
|
||||||
* and all RAM is below 256 bytes (tiny memory model in IAR CC).
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ----------------------- Optional MCU Description ------------------------ */
|
/* ----------------------- Optional MCU Description ------------------------ */
|
||||||
|
|
||||||
/* The following configurations have working defaults in usbdrv.h. You
|
/* The following configurations have working defaults in usbdrv.h. You
|
||||||
@ -379,6 +352,6 @@ section at the end of this file).
|
|||||||
/* #define USB_INTR_ENABLE_BIT INT0 */
|
/* #define USB_INTR_ENABLE_BIT INT0 */
|
||||||
/* #define USB_INTR_PENDING GIFR */
|
/* #define USB_INTR_PENDING GIFR */
|
||||||
/* #define USB_INTR_PENDING_BIT INTF0 */
|
/* #define USB_INTR_PENDING_BIT INTF0 */
|
||||||
/* #define USB_INTR_VECTOR INT0_vect */
|
/* #define USB_INTR_VECTOR SIG_INTERRUPT0 */
|
||||||
|
|
||||||
#endif /* __usbconfig_h_included__ */
|
#endif /* __usbconfig_h_included__ */
|
||||||
|
|||||||
@ -5,8 +5,10 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: usbdrv.c 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "usbportability.h"
|
||||||
#include "usbdrv.h"
|
#include "usbdrv.h"
|
||||||
#include "oddebug.h"
|
#include "oddebug.h"
|
||||||
|
|
||||||
@ -43,7 +45,7 @@ uchar usbCurrentDataToken;/* when we check data toggling to ignore duplica
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* USB status registers / not shared with asm code */
|
/* USB status registers / not shared with asm code */
|
||||||
usbMsgPtr_t usbMsgPtr; /* data to transmit next -- ROM or RAM address */
|
uchar *usbMsgPtr; /* data to transmit next -- ROM or RAM address */
|
||||||
static usbMsgLen_t usbMsgLen = USB_NO_MSG; /* remaining number of bytes */
|
static usbMsgLen_t usbMsgLen = USB_NO_MSG; /* remaining number of bytes */
|
||||||
static uchar usbMsgFlags; /* flag values see below */
|
static uchar usbMsgFlags; /* flag values see below */
|
||||||
|
|
||||||
@ -65,7 +67,7 @@ optimizing hints:
|
|||||||
#if USB_CFG_DESCR_PROPS_STRING_0 == 0
|
#if USB_CFG_DESCR_PROPS_STRING_0 == 0
|
||||||
#undef USB_CFG_DESCR_PROPS_STRING_0
|
#undef USB_CFG_DESCR_PROPS_STRING_0
|
||||||
#define USB_CFG_DESCR_PROPS_STRING_0 sizeof(usbDescriptorString0)
|
#define USB_CFG_DESCR_PROPS_STRING_0 sizeof(usbDescriptorString0)
|
||||||
PROGMEM const char usbDescriptorString0[] = { /* language descriptor */
|
PROGMEM char usbDescriptorString0[] = { /* language descriptor */
|
||||||
4, /* sizeof(usbDescriptorString0): length of descriptor in bytes */
|
4, /* sizeof(usbDescriptorString0): length of descriptor in bytes */
|
||||||
3, /* descriptor type */
|
3, /* descriptor type */
|
||||||
0x09, 0x04, /* language index (0x0409 = US-English) */
|
0x09, 0x04, /* language index (0x0409 = US-English) */
|
||||||
@ -75,7 +77,7 @@ PROGMEM const char usbDescriptorString0[] = { /* language descriptor */
|
|||||||
#if USB_CFG_DESCR_PROPS_STRING_VENDOR == 0 && USB_CFG_VENDOR_NAME_LEN
|
#if USB_CFG_DESCR_PROPS_STRING_VENDOR == 0 && USB_CFG_VENDOR_NAME_LEN
|
||||||
#undef USB_CFG_DESCR_PROPS_STRING_VENDOR
|
#undef USB_CFG_DESCR_PROPS_STRING_VENDOR
|
||||||
#define USB_CFG_DESCR_PROPS_STRING_VENDOR sizeof(usbDescriptorStringVendor)
|
#define USB_CFG_DESCR_PROPS_STRING_VENDOR sizeof(usbDescriptorStringVendor)
|
||||||
PROGMEM const int usbDescriptorStringVendor[] = {
|
PROGMEM int usbDescriptorStringVendor[] = {
|
||||||
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_VENDOR_NAME_LEN),
|
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_VENDOR_NAME_LEN),
|
||||||
USB_CFG_VENDOR_NAME
|
USB_CFG_VENDOR_NAME
|
||||||
};
|
};
|
||||||
@ -84,7 +86,7 @@ PROGMEM const int usbDescriptorStringVendor[] = {
|
|||||||
#if USB_CFG_DESCR_PROPS_STRING_PRODUCT == 0 && USB_CFG_DEVICE_NAME_LEN
|
#if USB_CFG_DESCR_PROPS_STRING_PRODUCT == 0 && USB_CFG_DEVICE_NAME_LEN
|
||||||
#undef USB_CFG_DESCR_PROPS_STRING_PRODUCT
|
#undef USB_CFG_DESCR_PROPS_STRING_PRODUCT
|
||||||
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT sizeof(usbDescriptorStringDevice)
|
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT sizeof(usbDescriptorStringDevice)
|
||||||
PROGMEM const int usbDescriptorStringDevice[] = {
|
PROGMEM int usbDescriptorStringDevice[] = {
|
||||||
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_DEVICE_NAME_LEN),
|
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_DEVICE_NAME_LEN),
|
||||||
USB_CFG_DEVICE_NAME
|
USB_CFG_DEVICE_NAME
|
||||||
};
|
};
|
||||||
@ -93,7 +95,7 @@ PROGMEM const int usbDescriptorStringDevice[] = {
|
|||||||
#if USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER == 0 && USB_CFG_SERIAL_NUMBER_LEN
|
#if USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER == 0 && USB_CFG_SERIAL_NUMBER_LEN
|
||||||
#undef USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
|
#undef USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
|
||||||
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER sizeof(usbDescriptorStringSerialNumber)
|
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER sizeof(usbDescriptorStringSerialNumber)
|
||||||
PROGMEM const int usbDescriptorStringSerialNumber[] = {
|
PROGMEM int usbDescriptorStringSerialNumber[] = {
|
||||||
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_SERIAL_NUMBER_LEN),
|
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_SERIAL_NUMBER_LEN),
|
||||||
USB_CFG_SERIAL_NUMBER
|
USB_CFG_SERIAL_NUMBER
|
||||||
};
|
};
|
||||||
@ -106,7 +108,7 @@ PROGMEM const int usbDescriptorStringSerialNumber[] = {
|
|||||||
#if USB_CFG_DESCR_PROPS_DEVICE == 0
|
#if USB_CFG_DESCR_PROPS_DEVICE == 0
|
||||||
#undef USB_CFG_DESCR_PROPS_DEVICE
|
#undef USB_CFG_DESCR_PROPS_DEVICE
|
||||||
#define USB_CFG_DESCR_PROPS_DEVICE sizeof(usbDescriptorDevice)
|
#define USB_CFG_DESCR_PROPS_DEVICE sizeof(usbDescriptorDevice)
|
||||||
PROGMEM const char usbDescriptorDevice[] = { /* USB device descriptor */
|
PROGMEM char usbDescriptorDevice[] = { /* USB device descriptor */
|
||||||
18, /* sizeof(usbDescriptorDevice): length of descriptor in bytes */
|
18, /* sizeof(usbDescriptorDevice): length of descriptor in bytes */
|
||||||
USBDESCR_DEVICE, /* descriptor type */
|
USBDESCR_DEVICE, /* descriptor type */
|
||||||
0x10, 0x01, /* USB version supported */
|
0x10, 0x01, /* USB version supported */
|
||||||
@ -137,7 +139,7 @@ PROGMEM const char usbDescriptorDevice[] = { /* USB device descriptor */
|
|||||||
#if USB_CFG_DESCR_PROPS_CONFIGURATION == 0
|
#if USB_CFG_DESCR_PROPS_CONFIGURATION == 0
|
||||||
#undef USB_CFG_DESCR_PROPS_CONFIGURATION
|
#undef USB_CFG_DESCR_PROPS_CONFIGURATION
|
||||||
#define USB_CFG_DESCR_PROPS_CONFIGURATION sizeof(usbDescriptorConfiguration)
|
#define USB_CFG_DESCR_PROPS_CONFIGURATION sizeof(usbDescriptorConfiguration)
|
||||||
PROGMEM const char usbDescriptorConfiguration[] = { /* USB configuration descriptor */
|
PROGMEM char usbDescriptorConfiguration[] = { /* USB configuration descriptor */
|
||||||
9, /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */
|
9, /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */
|
||||||
USBDESCR_CONFIG, /* descriptor type */
|
USBDESCR_CONFIG, /* descriptor type */
|
||||||
18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT3 +
|
18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT3 +
|
||||||
@ -147,9 +149,9 @@ PROGMEM const char usbDescriptorConfiguration[] = { /* USB configuration desc
|
|||||||
1, /* index of this configuration */
|
1, /* index of this configuration */
|
||||||
0, /* configuration name string index */
|
0, /* configuration name string index */
|
||||||
#if USB_CFG_IS_SELF_POWERED
|
#if USB_CFG_IS_SELF_POWERED
|
||||||
(1 << 7) | USBATTR_SELFPOWER, /* attributes */
|
USBATTR_SELFPOWER, /* attributes */
|
||||||
#else
|
#else
|
||||||
(1 << 7), /* attributes */
|
(char)USBATTR_BUSPOWER, /* attributes */
|
||||||
#endif
|
#endif
|
||||||
USB_CFG_MAX_BUS_POWER/2, /* max USB current in 2mA units */
|
USB_CFG_MAX_BUS_POWER/2, /* max USB current in 2mA units */
|
||||||
/* interface descriptor follows inline: */
|
/* interface descriptor follows inline: */
|
||||||
@ -182,7 +184,7 @@ PROGMEM const char usbDescriptorConfiguration[] = { /* USB configuration desc
|
|||||||
#if USB_CFG_HAVE_INTRIN_ENDPOINT3 /* endpoint descriptor for endpoint 3 */
|
#if USB_CFG_HAVE_INTRIN_ENDPOINT3 /* endpoint descriptor for endpoint 3 */
|
||||||
7, /* sizeof(usbDescrEndpoint) */
|
7, /* sizeof(usbDescrEndpoint) */
|
||||||
USBDESCR_ENDPOINT, /* descriptor type = endpoint */
|
USBDESCR_ENDPOINT, /* descriptor type = endpoint */
|
||||||
(char)(0x80 | USB_CFG_EP3_NUMBER), /* IN endpoint number 3 */
|
(char)0x83, /* IN endpoint number 1 */
|
||||||
0x03, /* attrib: Interrupt endpoint */
|
0x03, /* attrib: Interrupt endpoint */
|
||||||
8, 0, /* maximum packet size */
|
8, 0, /* maximum packet size */
|
||||||
USB_CFG_INTR_POLL_INTERVAL, /* in ms */
|
USB_CFG_INTR_POLL_INTERVAL, /* in ms */
|
||||||
@ -299,7 +301,7 @@ USB_PUBLIC void usbSetInterrupt3(uchar *data, uchar len)
|
|||||||
len = usbFunctionDescriptor(rq); \
|
len = usbFunctionDescriptor(rq); \
|
||||||
}else{ \
|
}else{ \
|
||||||
len = USB_PROP_LENGTH(cfgProp); \
|
len = USB_PROP_LENGTH(cfgProp); \
|
||||||
usbMsgPtr = (usbMsgPtr_t)(staticName); \
|
usbMsgPtr = (uchar *)(staticName); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,8 +361,7 @@ uchar flags = USB_FLG_MSGPTR_IS_ROM;
|
|||||||
*/
|
*/
|
||||||
static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq)
|
static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq)
|
||||||
{
|
{
|
||||||
usbMsgLen_t len = 0;
|
uchar len = 0, *dataPtr = usbTxBuf + 9; /* there are 2 bytes free space at the end of the buffer */
|
||||||
uchar *dataPtr = usbTxBuf + 9; /* there are 2 bytes free space at the end of the buffer */
|
|
||||||
uchar value = rq->wValue.bytes[0];
|
uchar value = rq->wValue.bytes[0];
|
||||||
#if USB_CFG_IMPLEMENT_HALT
|
#if USB_CFG_IMPLEMENT_HALT
|
||||||
uchar index = rq->wIndex.bytes[0];
|
uchar index = rq->wIndex.bytes[0];
|
||||||
@ -407,7 +408,7 @@ uchar index = rq->wIndex.bytes[0];
|
|||||||
SWITCH_DEFAULT /* 7=SET_DESCRIPTOR, 12=SYNC_FRAME */
|
SWITCH_DEFAULT /* 7=SET_DESCRIPTOR, 12=SYNC_FRAME */
|
||||||
/* Should we add an optional hook here? */
|
/* Should we add an optional hook here? */
|
||||||
SWITCH_END
|
SWITCH_END
|
||||||
usbMsgPtr = (usbMsgPtr_t)dataPtr;
|
usbMsgPtr = dataPtr;
|
||||||
skipMsgPtrAssignment:
|
skipMsgPtrAssignment:
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@ -497,8 +498,7 @@ static uchar usbDeviceRead(uchar *data, uchar len)
|
|||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
uchar i = len;
|
uchar i = len, *r = usbMsgPtr;
|
||||||
usbMsgPtr_t r = usbMsgPtr;
|
|
||||||
if(usbMsgFlags & USB_FLG_MSGPTR_IS_ROM){ /* ROM data */
|
if(usbMsgFlags & USB_FLG_MSGPTR_IS_ROM){ /* ROM data */
|
||||||
do{
|
do{
|
||||||
uchar c = USB_READ_FLASH(r); /* assign to char size variable to enforce byte ops */
|
uchar c = USB_READ_FLASH(r); /* assign to char size variable to enforce byte ops */
|
||||||
@ -507,8 +507,7 @@ static uchar usbDeviceRead(uchar *data, uchar len)
|
|||||||
}while(--i);
|
}while(--i);
|
||||||
}else{ /* RAM data */
|
}else{ /* RAM data */
|
||||||
do{
|
do{
|
||||||
*data++ = *((uchar *)r);
|
*data++ = *r++;
|
||||||
r++;
|
|
||||||
}while(--i);
|
}while(--i);
|
||||||
}
|
}
|
||||||
usbMsgPtr = r;
|
usbMsgPtr = r;
|
||||||
@ -558,8 +557,6 @@ uchar isReset = !notResetState;
|
|||||||
USB_RESET_HOOK(isReset);
|
USB_RESET_HOOK(isReset);
|
||||||
wasReset = isReset;
|
wasReset = isReset;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
notResetState = notResetState; // avoid compiler warning
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: usbdrv.h 748 2009-04-15 15:05:07Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __usbdrv_h_included__
|
#ifndef __usbdrv_h_included__
|
||||||
@ -104,9 +105,9 @@ interrupt routine.
|
|||||||
Interrupt latency:
|
Interrupt latency:
|
||||||
The application must ensure that the USB interrupt is not disabled for more
|
The application must ensure that the USB interrupt is not disabled for more
|
||||||
than 25 cycles (this is for 12 MHz, faster clocks allow longer latency).
|
than 25 cycles (this is for 12 MHz, faster clocks allow longer latency).
|
||||||
This implies that all interrupt routines must either have the "ISR_NOBLOCK"
|
This implies that all interrupt routines must either be declared as "INTERRUPT"
|
||||||
attribute set (see "avr/interrupt.h") or be written in assembler with "sei"
|
instead of "SIGNAL" (see "avr/signal.h") or that they are written in assembler
|
||||||
as the first instruction.
|
with "sei" as the first instruction.
|
||||||
|
|
||||||
Maximum interrupt duration / CPU cycle consumption:
|
Maximum interrupt duration / CPU cycle consumption:
|
||||||
The driver handles all USB communication during the interrupt service
|
The driver handles all USB communication during the interrupt service
|
||||||
@ -121,7 +122,7 @@ USB messages, even if they address another (low-speed) device on the same bus.
|
|||||||
/* --------------------------- Module Interface ---------------------------- */
|
/* --------------------------- Module Interface ---------------------------- */
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#define USBDRV_VERSION 20121206
|
#define USBDRV_VERSION 20090415
|
||||||
/* This define uniquely identifies a driver version. It is a decimal number
|
/* This define uniquely identifies a driver version. It is a decimal number
|
||||||
* constructed from the driver's release date in the form YYYYMMDD. If the
|
* constructed from the driver's release date in the form YYYYMMDD. If the
|
||||||
* driver's behavior or interface changes, you can use this constant to
|
* driver's behavior or interface changes, you can use this constant to
|
||||||
@ -162,24 +163,11 @@ USB messages, even if they address another (low-speed) device on the same bus.
|
|||||||
*/
|
*/
|
||||||
#define USB_NO_MSG ((usbMsgLen_t)-1) /* constant meaning "no message" */
|
#define USB_NO_MSG ((usbMsgLen_t)-1) /* constant meaning "no message" */
|
||||||
|
|
||||||
#ifndef usbMsgPtr_t
|
|
||||||
#define usbMsgPtr_t uchar *
|
|
||||||
#endif
|
|
||||||
/* Making usbMsgPtr_t a define allows the user of this library to define it to
|
|
||||||
* an 8 bit type on tiny devices. This reduces code size, especially if the
|
|
||||||
* compiler supports a tiny memory model.
|
|
||||||
* The type can be a pointer or scalar type, casts are made where necessary.
|
|
||||||
* Although it's paradoxical, Gcc 4 generates slightly better code for scalar
|
|
||||||
* types than for pointers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct usbRequest; /* forward declaration */
|
struct usbRequest; /* forward declaration */
|
||||||
|
|
||||||
USB_PUBLIC void usbInit(void);
|
USB_PUBLIC void usbInit(void);
|
||||||
/* This function must be called before interrupts are enabled and the main
|
/* This function must be called before interrupts are enabled and the main
|
||||||
* loop is entered. We exepct that the PORT and DDR bits for D+ and D- have
|
* loop is entered.
|
||||||
* not been changed from their default status (which is 0). If you have changed
|
|
||||||
* them, set both back to 0 (configure them as input with no internal pull-up).
|
|
||||||
*/
|
*/
|
||||||
USB_PUBLIC void usbPoll(void);
|
USB_PUBLIC void usbPoll(void);
|
||||||
/* This function must be called at regular intervals from the main loop.
|
/* This function must be called at regular intervals from the main loop.
|
||||||
@ -188,7 +176,7 @@ USB_PUBLIC void usbPoll(void);
|
|||||||
* Please note that debug outputs through the UART take ~ 0.5ms per byte
|
* Please note that debug outputs through the UART take ~ 0.5ms per byte
|
||||||
* at 19200 bps.
|
* at 19200 bps.
|
||||||
*/
|
*/
|
||||||
extern usbMsgPtr_t usbMsgPtr;
|
extern uchar *usbMsgPtr;
|
||||||
/* This variable may be used to pass transmit data to the driver from the
|
/* This variable may be used to pass transmit data to the driver from the
|
||||||
* implementation of usbFunctionWrite(). It is also used internally by the
|
* implementation of usbFunctionWrite(). It is also used internally by the
|
||||||
* driver for standard control requests.
|
* driver for standard control requests.
|
||||||
@ -400,13 +388,13 @@ extern volatile schar usbRxLen;
|
|||||||
* about the various methods to define USB descriptors. If you do nothing,
|
* about the various methods to define USB descriptors. If you do nothing,
|
||||||
* the default descriptors will be used.
|
* the default descriptors will be used.
|
||||||
*/
|
*/
|
||||||
#define USB_PROP_IS_DYNAMIC (1u << 14)
|
#define USB_PROP_IS_DYNAMIC (1 << 14)
|
||||||
/* If this property is set for a descriptor, usbFunctionDescriptor() will be
|
/* If this property is set for a descriptor, usbFunctionDescriptor() will be
|
||||||
* used to obtain the particular descriptor. Data directly returned via
|
* used to obtain the particular descriptor. Data directly returned via
|
||||||
* usbMsgPtr are FLASH data by default, combine (OR) with USB_PROP_IS_RAM to
|
* usbMsgPtr are FLASH data by default, combine (OR) with USB_PROP_IS_RAM to
|
||||||
* return RAM data.
|
* return RAM data.
|
||||||
*/
|
*/
|
||||||
#define USB_PROP_IS_RAM (1u << 15)
|
#define USB_PROP_IS_RAM (1 << 15)
|
||||||
/* If this property is set for a descriptor, the data is read from RAM
|
/* If this property is set for a descriptor, the data is read from RAM
|
||||||
* memory instead of Flash. The property is used for all methods to provide
|
* memory instead of Flash. The property is used for all methods to provide
|
||||||
* external descriptors.
|
* external descriptors.
|
||||||
@ -460,43 +448,43 @@ extern volatile schar usbRxLen;
|
|||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
extern
|
extern
|
||||||
#if !(USB_CFG_DESCR_PROPS_DEVICE & USB_PROP_IS_RAM)
|
#if !(USB_CFG_DESCR_PROPS_DEVICE & USB_PROP_IS_RAM)
|
||||||
PROGMEM const
|
PROGMEM
|
||||||
#endif
|
#endif
|
||||||
char usbDescriptorDevice[];
|
char usbDescriptorDevice[];
|
||||||
|
|
||||||
extern
|
extern
|
||||||
#if !(USB_CFG_DESCR_PROPS_CONFIGURATION & USB_PROP_IS_RAM)
|
#if !(USB_CFG_DESCR_PROPS_CONFIGURATION & USB_PROP_IS_RAM)
|
||||||
PROGMEM const
|
PROGMEM
|
||||||
#endif
|
#endif
|
||||||
char usbDescriptorConfiguration[];
|
char usbDescriptorConfiguration[];
|
||||||
|
|
||||||
extern
|
extern
|
||||||
#if !(USB_CFG_DESCR_PROPS_HID_REPORT & USB_PROP_IS_RAM)
|
#if !(USB_CFG_DESCR_PROPS_HID_REPORT & USB_PROP_IS_RAM)
|
||||||
PROGMEM const
|
PROGMEM
|
||||||
#endif
|
#endif
|
||||||
char usbDescriptorHidReport[];
|
char usbDescriptorHidReport[];
|
||||||
|
|
||||||
extern
|
extern
|
||||||
#if !(USB_CFG_DESCR_PROPS_STRING_0 & USB_PROP_IS_RAM)
|
#if !(USB_CFG_DESCR_PROPS_STRING_0 & USB_PROP_IS_RAM)
|
||||||
PROGMEM const
|
PROGMEM
|
||||||
#endif
|
#endif
|
||||||
char usbDescriptorString0[];
|
char usbDescriptorString0[];
|
||||||
|
|
||||||
extern
|
extern
|
||||||
#if !(USB_CFG_DESCR_PROPS_STRING_VENDOR & USB_PROP_IS_RAM)
|
#if !(USB_CFG_DESCR_PROPS_STRING_VENDOR & USB_PROP_IS_RAM)
|
||||||
PROGMEM const
|
PROGMEM
|
||||||
#endif
|
#endif
|
||||||
int usbDescriptorStringVendor[];
|
int usbDescriptorStringVendor[];
|
||||||
|
|
||||||
extern
|
extern
|
||||||
#if !(USB_CFG_DESCR_PROPS_STRING_PRODUCT & USB_PROP_IS_RAM)
|
#if !(USB_CFG_DESCR_PROPS_STRING_PRODUCT & USB_PROP_IS_RAM)
|
||||||
PROGMEM const
|
PROGMEM
|
||||||
#endif
|
#endif
|
||||||
int usbDescriptorStringDevice[];
|
int usbDescriptorStringDevice[];
|
||||||
|
|
||||||
extern
|
extern
|
||||||
#if !(USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER & USB_PROP_IS_RAM)
|
#if !(USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER & USB_PROP_IS_RAM)
|
||||||
PROGMEM const
|
PROGMEM
|
||||||
#endif
|
#endif
|
||||||
int usbDescriptorStringSerialNumber[];
|
int usbDescriptorStringSerialNumber[];
|
||||||
|
|
||||||
@ -523,22 +511,22 @@ int usbDescriptorStringSerialNumber[];
|
|||||||
#if !defined __ASSEMBLER__ && (!defined USB_CFG_VENDOR_ID || !defined USB_CFG_DEVICE_ID)
|
#if !defined __ASSEMBLER__ && (!defined USB_CFG_VENDOR_ID || !defined USB_CFG_DEVICE_ID)
|
||||||
#warning "You should define USB_CFG_VENDOR_ID and USB_CFG_DEVICE_ID in usbconfig.h"
|
#warning "You should define USB_CFG_VENDOR_ID and USB_CFG_DEVICE_ID in usbconfig.h"
|
||||||
/* If the user has not defined IDs, we default to obdev's free IDs.
|
/* If the user has not defined IDs, we default to obdev's free IDs.
|
||||||
* See USB-IDs-for-free.txt for details.
|
* See USBID-License.txt for details.
|
||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* make sure we have a VID and PID defined, byte order is lowbyte, highbyte */
|
/* make sure we have a VID and PID defined, byte order is lowbyte, highbyte */
|
||||||
#ifndef USB_CFG_VENDOR_ID
|
#ifndef USB_CFG_VENDOR_ID
|
||||||
# define USB_CFG_VENDOR_ID 0xc0, 0x16 /* = 0x16c0 = 5824 = voti.nl */
|
# define USB_CFG_VENDOR_ID 0xc0, 0x16 /* 5824 in dec, stands for VOTI */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef USB_CFG_DEVICE_ID
|
#ifndef USB_CFG_DEVICE_ID
|
||||||
# if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH
|
# if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH
|
||||||
# define USB_CFG_DEVICE_ID 0xdf, 0x05 /* = 0x5df = 1503, shared PID for HIDs */
|
# define USB_CFG_DEVICE_ID 0xdf, 0x05 /* 1503 in dec, shared PID for HIDs */
|
||||||
# elif USB_CFG_INTERFACE_CLASS == 2
|
# elif USB_CFG_INTERFACE_CLASS == 2
|
||||||
# define USB_CFG_DEVICE_ID 0xe1, 0x05 /* = 0x5e1 = 1505, shared PID for CDC Modems */
|
# define USB_CFG_DEVICE_ID 0xe1, 0x05 /* 1505 in dec, shared PID for CDC Modems */
|
||||||
# else
|
# else
|
||||||
# define USB_CFG_DEVICE_ID 0xdc, 0x05 /* = 0x5dc = 1500, obdev's free PID */
|
# define USB_CFG_DEVICE_ID 0xdc, 0x05 /* 1500 in dec, obdev's free PID */
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -728,8 +716,7 @@ typedef struct usbRequest{
|
|||||||
#define USBDESCR_HID_REPORT 0x22
|
#define USBDESCR_HID_REPORT 0x22
|
||||||
#define USBDESCR_HID_PHYS 0x23
|
#define USBDESCR_HID_PHYS 0x23
|
||||||
|
|
||||||
//#define USBATTR_BUSPOWER 0x80 // USB 1.1 does not define this value any more
|
#define USBATTR_BUSPOWER 0x80
|
||||||
#define USBATTR_BUSPOWER 0
|
|
||||||
#define USBATTR_SELFPOWER 0x40
|
#define USBATTR_SELFPOWER 0x40
|
||||||
#define USBATTR_REMOTEWAKE 0x20
|
#define USBATTR_REMOTEWAKE 0x20
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* Revision: $Id: usbdrvasm.S 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -56,11 +57,7 @@ the file appropriate for the given clock rate.
|
|||||||
#else /* __IAR_SYSTEMS_ASM__ */
|
#else /* __IAR_SYSTEMS_ASM__ */
|
||||||
|
|
||||||
# ifndef USB_INTR_VECTOR /* default to hardware interrupt INT0 */
|
# ifndef USB_INTR_VECTOR /* default to hardware interrupt INT0 */
|
||||||
# ifdef INT0_vect
|
# define USB_INTR_VECTOR SIG_INTERRUPT0
|
||||||
# define USB_INTR_VECTOR INT0_vect // this is the "new" define for the vector
|
|
||||||
# else
|
|
||||||
# define USB_INTR_VECTOR SIG_INTERRUPT0 // this is the "old" vector
|
|
||||||
# endif
|
|
||||||
# endif
|
# endif
|
||||||
.text
|
.text
|
||||||
.global USB_INTR_VECTOR
|
.global USB_INTR_VECTOR
|
||||||
@ -142,93 +139,16 @@ RTMODEL "__rt_version", "3"
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USB_USE_FAST_CRC
|
; extern unsigned usbCrc16(unsigned char *data, unsigned char len);
|
||||||
|
; data: r24/25
|
||||||
; This implementation is faster, but has bigger code size
|
; len: r22
|
||||||
; Thanks to Slawomir Fras (BoskiDialer) for this code!
|
|
||||||
; It implements the following C pseudo-code:
|
|
||||||
; unsigned table(unsigned char x)
|
|
||||||
; {
|
|
||||||
; unsigned value;
|
|
||||||
;
|
|
||||||
; value = (unsigned)x << 6;
|
|
||||||
; value ^= (unsigned)x << 7;
|
|
||||||
; if(parity(x))
|
|
||||||
; value ^= 0xc001;
|
|
||||||
; return value;
|
|
||||||
; }
|
|
||||||
; unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen)
|
|
||||||
; {
|
|
||||||
; unsigned crc = 0xffff;
|
|
||||||
;
|
|
||||||
; while(argLen--)
|
|
||||||
; crc = table(lo8(crc) ^ *argPtr++) ^ hi8(crc);
|
|
||||||
; return ~crc;
|
|
||||||
; }
|
|
||||||
|
|
||||||
; extern unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen);
|
|
||||||
; argPtr r24+25 / r16+r17
|
|
||||||
; argLen r22 / r18
|
|
||||||
; temp variables:
|
; temp variables:
|
||||||
; byte r18 / r22
|
; r18: data byte
|
||||||
; scratch r23
|
; r19: bit counter
|
||||||
; resCrc r24+r25 / r16+r17
|
; r20/21: polynomial
|
||||||
; ptr X / Z
|
; r23: scratch
|
||||||
usbCrc16:
|
; r24/25: crc-sum
|
||||||
mov ptrL, argPtrL
|
; r26/27=X: ptr
|
||||||
mov ptrH, argPtrH
|
|
||||||
ldi resCrcL, 0xFF
|
|
||||||
ldi resCrcH, 0xFF
|
|
||||||
rjmp usbCrc16LoopTest
|
|
||||||
usbCrc16ByteLoop:
|
|
||||||
ld byte, ptr+
|
|
||||||
eor resCrcL, byte ; resCrcL is now 'x' in table()
|
|
||||||
mov byte, resCrcL ; compute parity of 'x'
|
|
||||||
swap byte
|
|
||||||
eor byte, resCrcL
|
|
||||||
mov scratch, byte
|
|
||||||
lsr byte
|
|
||||||
lsr byte
|
|
||||||
eor byte, scratch
|
|
||||||
inc byte
|
|
||||||
lsr byte
|
|
||||||
andi byte, 1 ; byte is now parity(x)
|
|
||||||
mov scratch, resCrcL
|
|
||||||
mov resCrcL, resCrcH
|
|
||||||
eor resCrcL, byte ; low byte of if(parity(x)) value ^= 0xc001;
|
|
||||||
neg byte
|
|
||||||
andi byte, 0xc0
|
|
||||||
mov resCrcH, byte ; high byte of if(parity(x)) value ^= 0xc001;
|
|
||||||
clr byte
|
|
||||||
lsr scratch
|
|
||||||
ror byte
|
|
||||||
eor resCrcH, scratch
|
|
||||||
eor resCrcL, byte
|
|
||||||
lsr scratch
|
|
||||||
ror byte
|
|
||||||
eor resCrcH, scratch
|
|
||||||
eor resCrcL, byte
|
|
||||||
usbCrc16LoopTest:
|
|
||||||
subi argLen, 1
|
|
||||||
brsh usbCrc16ByteLoop
|
|
||||||
com resCrcL
|
|
||||||
com resCrcH
|
|
||||||
ret
|
|
||||||
|
|
||||||
#else /* USB_USE_FAST_CRC */
|
|
||||||
|
|
||||||
; This implementation is slower, but has less code size
|
|
||||||
;
|
|
||||||
; extern unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen);
|
|
||||||
; argPtr r24+25 / r16+r17
|
|
||||||
; argLen r22 / r18
|
|
||||||
; temp variables:
|
|
||||||
; byte r18 / r22
|
|
||||||
; bitCnt r19
|
|
||||||
; poly r20+r21
|
|
||||||
; scratch r23
|
|
||||||
; resCrc r24+r25 / r16+r17
|
|
||||||
; ptr X / Z
|
|
||||||
usbCrc16:
|
usbCrc16:
|
||||||
mov ptrL, argPtrL
|
mov ptrL, argPtrL
|
||||||
mov ptrH, argPtrH
|
mov ptrH, argPtrH
|
||||||
@ -236,30 +156,27 @@ usbCrc16:
|
|||||||
ldi resCrcH, 0
|
ldi resCrcH, 0
|
||||||
ldi polyL, lo8(0xa001)
|
ldi polyL, lo8(0xa001)
|
||||||
ldi polyH, hi8(0xa001)
|
ldi polyH, hi8(0xa001)
|
||||||
com argLen ; argLen = -argLen - 1: modified loop to ensure that carry is set
|
com argLen ; argLen = -argLen - 1
|
||||||
ldi bitCnt, 0 ; loop counter with starnd condition = end condition
|
crcByteLoop:
|
||||||
rjmp usbCrcLoopEntry
|
subi argLen, -1
|
||||||
usbCrcByteLoop:
|
brcc crcReady ; modified loop to ensure that carry is set below
|
||||||
ld byte, ptr+
|
ld byte, ptr+
|
||||||
|
ldi bitCnt, -8 ; strange loop counter to ensure that carry is set where we need it
|
||||||
eor resCrcL, byte
|
eor resCrcL, byte
|
||||||
usbCrcBitLoop:
|
crcBitLoop:
|
||||||
ror resCrcH ; carry is always set here (see brcs jumps to here)
|
ror resCrcH ; carry is always set here
|
||||||
ror resCrcL
|
ror resCrcL
|
||||||
brcs usbCrcNoXor
|
brcs crcNoXor
|
||||||
eor resCrcL, polyL
|
eor resCrcL, polyL
|
||||||
eor resCrcH, polyH
|
eor resCrcH, polyH
|
||||||
usbCrcNoXor:
|
crcNoXor:
|
||||||
subi bitCnt, 224 ; (8 * 224) % 256 = 0; this loop iterates 8 times
|
subi bitCnt, -1
|
||||||
brcs usbCrcBitLoop
|
brcs crcBitLoop
|
||||||
usbCrcLoopEntry:
|
rjmp crcByteLoop
|
||||||
subi argLen, -1
|
crcReady:
|
||||||
brcs usbCrcByteLoop
|
|
||||||
usbCrcReady:
|
|
||||||
ret
|
ret
|
||||||
; Thanks to Reimar Doeffinger for optimizing this CRC routine!
|
; Thanks to Reimar Doeffinger for optimizing this CRC routine!
|
||||||
|
|
||||||
#endif /* USB_USE_FAST_CRC */
|
|
||||||
|
|
||||||
; extern unsigned usbCrc16Append(unsigned char *data, unsigned char len);
|
; extern unsigned usbCrc16Append(unsigned char *data, unsigned char len);
|
||||||
usbCrc16Append:
|
usbCrc16Append:
|
||||||
rcall usbCrc16
|
rcall usbCrc16
|
||||||
@ -360,11 +277,7 @@ usbMFTimeout:
|
|||||||
;----------------------------------------------------------------------------
|
;----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef USB_CFG_CLOCK_KHZ
|
#ifndef USB_CFG_CLOCK_KHZ
|
||||||
# ifdef F_CPU
|
# define USB_CFG_CLOCK_KHZ 12000
|
||||||
# define USB_CFG_CLOCK_KHZ (F_CPU/1000)
|
|
||||||
# else
|
|
||||||
# error "USB_CFG_CLOCK_KHZ not defined in usbconfig.h and no F_CPU set!"
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USB_CFG_CHECK_CRC /* separate dispatcher for CRC type modules */
|
#if USB_CFG_CHECK_CRC /* separate dispatcher for CRC type modules */
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: usbdrvasm12.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: usbdrvasm128.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
@ -30,9 +31,8 @@ limitations:
|
|||||||
They typical range is 14.5 MHz and most AVRs can actually reach this rate.
|
They typical range is 14.5 MHz and most AVRs can actually reach this rate.
|
||||||
(2) Writing EEPROM and Flash may be unreliable (short data lifetime) since
|
(2) Writing EEPROM and Flash may be unreliable (short data lifetime) since
|
||||||
the write procedure is timed from the RC oscillator.
|
the write procedure is timed from the RC oscillator.
|
||||||
(3) End Of Packet detection (SE0) should be in bit 1, bit it is only checked
|
(3) End Of Packet detection is between bit 0 and bit 1 where the EOP condition
|
||||||
if bits 0 and 1 both read as 0 on D- and D+ read as 0 in the middle. This may
|
may not be reliable when a hub is used. It should be in bit 1.
|
||||||
cause problems with old hubs which delay SE0 by up to one cycle.
|
|
||||||
(4) Code size is much larger than that of the other modules.
|
(4) Code size is much larger than that of the other modules.
|
||||||
|
|
||||||
Since almost all of this code is timing critical, don't change unless you
|
Since almost all of this code is timing critical, don't change unless you
|
||||||
@ -217,10 +217,8 @@ unstuff0s:
|
|||||||
ifioclr USBIN, USBMINUS ;[00]
|
ifioclr USBIN, USBMINUS ;[00]
|
||||||
ifioset USBIN, USBPLUS ;[01]
|
ifioset USBIN, USBPLUS ;[01]
|
||||||
rjmp bit0IsClr ;[02] executed if first expr false or second true
|
rjmp bit0IsClr ;[02] executed if first expr false or second true
|
||||||
se0AndStore: ; executed only if both bits 0
|
jumpToSe0AndStore:
|
||||||
st y+, x1 ;[15/17] cycles after start of byte
|
rjmp se0AndStore ;[03] executed only if both bits 0
|
||||||
rjmp se0 ;[17/19]
|
|
||||||
|
|
||||||
bit0IsClr:
|
bit0IsClr:
|
||||||
ifrset phase, USBMINUS ;[04] check phase only if D- changed
|
ifrset phase, USBMINUS ;[04] check phase only if D- changed
|
||||||
lpm ;[05]
|
lpm ;[05]
|
||||||
@ -230,7 +228,7 @@ bit1AfterClr:
|
|||||||
andi phase, USBMASK ;[08]
|
andi phase, USBMASK ;[08]
|
||||||
ifioset USBIN, USBMINUS ;[09] <--- sample 1
|
ifioset USBIN, USBMINUS ;[09] <--- sample 1
|
||||||
rjmp bit1IsSet ;[10]
|
rjmp bit1IsSet ;[10]
|
||||||
breq se0AndStore ;[11] if D- was 0 in bits 0 AND 1 and D+ was 0 in between, we have SE0
|
breq jumpToSe0AndStore ;[11]
|
||||||
andi shift, ~(7 << 1) ;[12]
|
andi shift, ~(7 << 1) ;[12]
|
||||||
in phase, USBIN ;[13] <- phase
|
in phase, USBIN ;[13] <- phase
|
||||||
breq unstuff1c ;[14]
|
breq unstuff1c ;[14]
|
||||||
@ -357,6 +355,10 @@ unstuff7c:
|
|||||||
nop ;[59]
|
nop ;[59]
|
||||||
rjmp bit7IsSet ;[60]
|
rjmp bit7IsSet ;[60]
|
||||||
|
|
||||||
|
se0AndStore:
|
||||||
|
st y+, x1 ;[15/17] cycles after start of byte
|
||||||
|
rjmp se0 ;[17/19]
|
||||||
|
|
||||||
bit7IsClr:
|
bit7IsClr:
|
||||||
ifrset phase, USBMINUS ;[62] check phase only if D- changed
|
ifrset phase, USBMINUS ;[62] check phase only if D- changed
|
||||||
lpm ;[63]
|
lpm ;[63]
|
||||||
@ -389,24 +391,25 @@ bit0IsSet:
|
|||||||
in phase, USBIN ;[06] <- phase (one cycle too late)
|
in phase, USBIN ;[06] <- phase (one cycle too late)
|
||||||
ori shift, 1 << 0 ;[07]
|
ori shift, 1 << 0 ;[07]
|
||||||
bit1AfterSet:
|
bit1AfterSet:
|
||||||
andi shift, ~(7 << 1) ;[08] compensated by "ori shift, 1<<1" if bit1IsClr
|
andi phase, USBMASK ;[08]
|
||||||
ifioclr USBIN, USBMINUS ;[09] <--- sample 1
|
ifioclr USBIN, USBMINUS ;[09] <--- sample 1
|
||||||
rjmp bit1IsClr ;[10]
|
rjmp bit1IsClr ;[10]
|
||||||
breq unstuff1s ;[11]
|
andi shift, ~(7 << 1) ;[11]
|
||||||
nop2 ;[12] do not check for SE0 if bit 0 was 1
|
breq unstuff1s ;[12]
|
||||||
in phase, USBIN ;[14] <- phase (one cycle too late)
|
in phase, USBIN ;[13] <- phase
|
||||||
|
nop ;[14]
|
||||||
rjmp bit2AfterSet ;[15]
|
rjmp bit2AfterSet ;[15]
|
||||||
unstuff1s:
|
unstuff1s:
|
||||||
in phase, USBIN ;[13] <- phase
|
in phase, USBIN ;[14] <- phase (one cycle too late)
|
||||||
andi fix, ~(1 << 1) ;[14]
|
andi fix, ~(1 << 1) ;[15]
|
||||||
lpm ;[07]
|
nop2 ;[08]
|
||||||
nop2 ;[10]
|
nop2 ;[10]
|
||||||
bit1IsClr:
|
bit1IsClr:
|
||||||
ifrset phase, USBMINUS ;[12] check phase only if D- changed
|
ifrset phase, USBMINUS ;[12] check phase only if D- changed
|
||||||
lpm ;[13]
|
lpm ;[13]
|
||||||
in phase, USBIN ;[14] <- phase (one cycle too late)
|
in phase, USBIN ;[14] <- phase (one cycle too late)
|
||||||
ori shift, 1 << 1 ;[15]
|
breq se0AndStore ;[15] if we come from unstuff1s, Z bit is never set
|
||||||
nop ;[16]
|
ori shift, 1 << 1 ;[16]
|
||||||
bit2AfterClr:
|
bit2AfterClr:
|
||||||
ifioset USBIN, USBMINUS ;[17] <--- sample 2
|
ifioset USBIN, USBMINUS ;[17] <--- sample 2
|
||||||
rjmp bit2IsSet ;[18]
|
rjmp bit2IsSet ;[18]
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* Revision: $Id: usbdrvasm15.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* Revision: $Id: usbdrvasm16.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
@ -116,15 +117,12 @@ haveTwoBitsK:
|
|||||||
; Receiver loop (numbers in brackets are cycles within byte after instr)
|
; Receiver loop (numbers in brackets are cycles within byte after instr)
|
||||||
;----------------------------------------------------------------------------
|
;----------------------------------------------------------------------------
|
||||||
|
|
||||||
; duration of unstuffing code should be 10.66666667 cycles. We adjust "leap"
|
|
||||||
; accordingly to approximate this value in the long run.
|
|
||||||
|
|
||||||
unstuff6:
|
unstuff6:
|
||||||
andi x2, USBMASK ;[03]
|
andi x2, USBMASK ;[03]
|
||||||
ori x3, 1<<6 ;[04] will not be shifted any more
|
ori x3, 1<<6 ;[04] will not be shifted any more
|
||||||
andi shift, ~0x80;[05]
|
andi shift, ~0x80;[05]
|
||||||
mov x1, x2 ;[06] sampled bit 7 is actually re-sampled bit 6
|
mov x1, x2 ;[06] sampled bit 7 is actually re-sampled bit 6
|
||||||
subi leap, -1 ;[07] total duration = 11 bits -> subtract 1/3
|
subi leap, 3 ;[07] since this is a short (10 cycle) bit, enforce leap bit
|
||||||
rjmp didUnstuff6 ;[08]
|
rjmp didUnstuff6 ;[08]
|
||||||
|
|
||||||
unstuff7:
|
unstuff7:
|
||||||
@ -132,7 +130,7 @@ unstuff7:
|
|||||||
in x2, USBIN ;[00] [10] re-sample bit 7
|
in x2, USBIN ;[00] [10] re-sample bit 7
|
||||||
andi x2, USBMASK ;[01]
|
andi x2, USBMASK ;[01]
|
||||||
andi shift, ~0x80;[02]
|
andi shift, ~0x80;[02]
|
||||||
subi leap, 2 ;[03] total duration = 10 bits -> add 1/3
|
subi leap, 3 ;[03] since this is a short (10 cycle) bit, enforce leap bit
|
||||||
rjmp didUnstuff7 ;[04]
|
rjmp didUnstuff7 ;[04]
|
||||||
|
|
||||||
unstuffEven:
|
unstuffEven:
|
||||||
@ -141,8 +139,8 @@ unstuffEven:
|
|||||||
andi shift, ~0x80;[01]
|
andi shift, ~0x80;[01]
|
||||||
andi x1, USBMASK ;[02]
|
andi x1, USBMASK ;[02]
|
||||||
breq se0 ;[03]
|
breq se0 ;[03]
|
||||||
subi leap, -1 ;[04] total duration = 11 bits -> subtract 1/3
|
subi leap, 3 ;[04] since this is a short (10 cycle) bit, enforce leap bit
|
||||||
nop2 ;[05]
|
nop ;[05]
|
||||||
rjmp didUnstuffE ;[06]
|
rjmp didUnstuffE ;[06]
|
||||||
|
|
||||||
unstuffOdd:
|
unstuffOdd:
|
||||||
@ -151,8 +149,8 @@ unstuffOdd:
|
|||||||
andi shift, ~0x80;[01]
|
andi shift, ~0x80;[01]
|
||||||
andi x2, USBMASK ;[02]
|
andi x2, USBMASK ;[02]
|
||||||
breq se0 ;[03]
|
breq se0 ;[03]
|
||||||
subi leap, -1 ;[04] total duration = 11 bits -> subtract 1/3
|
subi leap, 3 ;[04] since this is a short (10 cycle) bit, enforce leap bit
|
||||||
nop2 ;[05]
|
nop ;[05]
|
||||||
rjmp didUnstuffO ;[06]
|
rjmp didUnstuffO ;[06]
|
||||||
|
|
||||||
rxByteLoop:
|
rxByteLoop:
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* Revision: $Id: usbdrvasm165.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2008 by Lukas Schrittwieser and OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2008 by Lukas Schrittwieser and OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* Revision: $Id: usbdrvasm18-crc.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2008 by Jeroen Benschop and OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2008 by Jeroen Benschop and OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* Revision: $Id: usbdrvasm20.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: usbportability.h 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -124,11 +125,7 @@ static inline void sei(void)
|
|||||||
# include <avr/pgmspace.h>
|
# include <avr/pgmspace.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USB_CFG_DRIVER_FLASH_PAGE
|
|
||||||
# define USB_READ_FLASH(addr) pgm_read_byte_far(((long)USB_CFG_DRIVER_FLASH_PAGE << 16) | (long)(addr))
|
|
||||||
#else
|
|
||||||
#define USB_READ_FLASH(addr) pgm_read_byte(addr)
|
#define USB_READ_FLASH(addr) pgm_read_byte(addr)
|
||||||
#endif
|
|
||||||
|
|
||||||
#define macro .macro
|
#define macro .macro
|
||||||
#define endm .endm
|
#define endm .endm
|
||||||
|
|||||||
@ -1,145 +0,0 @@
|
|||||||
/*
|
|
||||||
* =====================================================================================
|
|
||||||
*
|
|
||||||
* ________ .__ __ ________ ____ ________
|
|
||||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
* \__> \/ \/ \/ \/ \/
|
|
||||||
*
|
|
||||||
* www.optixx.org
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Version: 1.0
|
|
||||||
* Created: 07/21/2009 03:32:16 PM
|
|
||||||
* Author: david@optixx.org
|
|
||||||
*
|
|
||||||
* =====================================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
uint8_t *util_strupper(uint8_t * s)
|
|
||||||
{
|
|
||||||
uint8_t *p;
|
|
||||||
for (p = s; *p != '\0'; p++)
|
|
||||||
if (*p >= 'a' && *p <= 'z')
|
|
||||||
*p += 'A' - 'a';
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *util_strlower(uint8_t * s)
|
|
||||||
{
|
|
||||||
uint8_t *p;
|
|
||||||
for (p = s; *p != '\0'; p++)
|
|
||||||
if (*p >= 'A' && *p <= 'Z')
|
|
||||||
*p += 'a' - 'A';
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void util_chomp(uint8_t * s)
|
|
||||||
{
|
|
||||||
uint16_t len;
|
|
||||||
|
|
||||||
len = strlen((char *) s);
|
|
||||||
if (len >= 2 && s[len - 1] == '\n' && s[len - 2] == '\r')
|
|
||||||
s[len - 2] = '\0';
|
|
||||||
else if (len >= 1 && (s[len - 1] == '\n' || s[len - 1] == '\r'))
|
|
||||||
s[len - 1] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
void util_trim(uint8_t * s)
|
|
||||||
{
|
|
||||||
uint8_t *p = s;
|
|
||||||
uint8_t *q;
|
|
||||||
/*
|
|
||||||
* skip leading whitespace
|
|
||||||
*/
|
|
||||||
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
|
|
||||||
p++;
|
|
||||||
/*
|
|
||||||
* now p points at the first non-whitespace uint8_tacter
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (*p == '\0') {
|
|
||||||
/*
|
|
||||||
* only whitespace
|
|
||||||
*/
|
|
||||||
*s = '\0';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
q = s + strlen((char *) s);
|
|
||||||
/*
|
|
||||||
* skip trailing whitespace
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* we have found p < q such that *p is non-whitespace, so this loop terminates with q >= p
|
|
||||||
*/
|
|
||||||
do
|
|
||||||
q--;
|
|
||||||
while (*q == ' ' || *q == '\t' || *q == '\r' || *q == '\n');
|
|
||||||
|
|
||||||
/*
|
|
||||||
* now q points at the last non-whitespace uint8_tacter
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* cut off trailing whitespace
|
|
||||||
*/
|
|
||||||
*++q = '\0';
|
|
||||||
|
|
||||||
/*
|
|
||||||
* move to string
|
|
||||||
*/
|
|
||||||
memmove(s, p, q + 1 - p);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t util_sscandec(const uint8_t * s)
|
|
||||||
{
|
|
||||||
uint32_t result;
|
|
||||||
if (*s == '\0')
|
|
||||||
return -1;
|
|
||||||
result = 0;
|
|
||||||
for (;;) {
|
|
||||||
if (*s >= '0' && *s <= '9')
|
|
||||||
result = 10 * result + *s - '0';
|
|
||||||
else if (*s == '\0')
|
|
||||||
return result;
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t util_sscanhex(const uint8_t * s)
|
|
||||||
{
|
|
||||||
int32_t result;
|
|
||||||
if (*s == '\0')
|
|
||||||
return -1;
|
|
||||||
result = 0;
|
|
||||||
for (;;) {
|
|
||||||
if (*s >= '0' && *s <= '9')
|
|
||||||
result = 16 * result + *s - '0';
|
|
||||||
else if (*s >= 'A' && *s <= 'F')
|
|
||||||
result = 16 * result + *s - 'A' + 10;
|
|
||||||
else if (*s >= 'a' && *s <= 'f')
|
|
||||||
result = 16 * result + *s - 'a' + 10;
|
|
||||||
else if (*s == '\0')
|
|
||||||
return result;
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t util_sscanbool(const uint8_t * s)
|
|
||||||
{
|
|
||||||
if (*s == '0' && s[1] == '\0')
|
|
||||||
return 0;
|
|
||||||
if (*s == '1' && s[1] == '\0')
|
|
||||||
return 1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* =====================================================================================
|
|
||||||
*
|
|
||||||
* ________ .__ __ ________ ____ ________
|
|
||||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
* \__> \/ \/ \/ \/ \/
|
|
||||||
*
|
|
||||||
* www.optixx.org
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Version: 1.0
|
|
||||||
* Created: 07/21/2009 03:32:16 PM
|
|
||||||
* Author: david@optixx.org
|
|
||||||
*
|
|
||||||
* =====================================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UTIL_H__
|
|
||||||
#define __UTIL_H__
|
|
||||||
|
|
||||||
uint8_t *util_strupper(uint8_t * s);
|
|
||||||
uint8_t *util_strlower(uint8_t * s);
|
|
||||||
void util_chomp(uint8_t * s);
|
|
||||||
void util_trim(uint8_t * s);
|
|
||||||
uint32_t util_sscandec(const uint8_t * s);
|
|
||||||
uint32_t util_sscanhex(const uint8_t * s);
|
|
||||||
uint8_t util_sscanbool(const uint8_t * s);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -28,3 +28,4 @@ void wdt_init(void)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -39,3 +39,4 @@ do \
|
|||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
10
done.txt
10
done.txt
@ -1,10 +0,0 @@
|
|||||||
x 2009-10-13 Send PCB to seeed
|
|
||||||
x 2009-10-13 RS232 cable add programm header and sio lines
|
|
||||||
x 2009-10-13 Assemble No. 006 & No. 007
|
|
||||||
x 2009-10-13 Flash all cartridge with latest firmware and bootloader
|
|
||||||
x 2009-10-13 Bootloader lockbits
|
|
||||||
x 2009-10-13 Rework No. 002
|
|
||||||
x 2009-10-13 Package for Quickdev16
|
|
||||||
x 2009-10-13 Add struct for usb and communcations flags
|
|
||||||
x 2009-10-13 Mail snega2usb about OEM
|
|
||||||
x 2009-10-13 Email to seeed about the retour package
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
--------------------------------
|
|
||||||
SDcard Board
|
|
||||||
--------------------------------
|
|
||||||
Connector
|
|
||||||
|
|
||||||
1 DO -> 7
|
|
||||||
2 GND -> 6
|
|
||||||
3 VCC -> 4
|
|
||||||
4 CS -> 1
|
|
||||||
5 DI -> 2
|
|
||||||
6 CLK -> 5
|
|
||||||
-
|
|
||||||
SDcard
|
|
||||||
------------------\
|
|
||||||
| \
|
|
||||||
| 8 7 6 5 4 3 2 1 9 |
|
|
||||||
| |
|
|
||||||
|
|
||||||
1 CS
|
|
||||||
2 CMD/DI
|
|
||||||
3 GND
|
|
||||||
4 VCC
|
|
||||||
5 CLK/SCLK
|
|
||||||
6 GND
|
|
||||||
7 DAT/DO
|
|
||||||
8 --
|
|
||||||
9 --
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------
|
|
||||||
Quickdev Header
|
|
||||||
--------------------------------
|
|
||||||
top/usb
|
|
||||||
1 GND -> GND
|
|
||||||
2 ISP RST - RESET -
|
|
||||||
3 ISP SCK - PB7 - CLK
|
|
||||||
4 ISP MISO - PB6 - DI
|
|
||||||
5 ISP MOSI - PB5 - DO
|
|
||||||
6 MMC CS - PB4 - CS
|
|
||||||
7 VCC -> VCC
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define SPI_DI 6 MISO
|
|
||||||
#define SPI_DO 5 MOSI
|
|
||||||
Binary file not shown.
Binary file not shown.
@ -1,29 +0,0 @@
|
|||||||
________ .__ __ ________ ____ ________
|
|
||||||
\_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
/ / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
/ \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
\_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
\__> \/ \/ \/ \/ \/
|
|
||||||
___.
|
|
||||||
__ __ _____\_ |__
|
|
||||||
| | \/ ___/| __ \
|
|
||||||
| | /\___ \ | \_\ \
|
|
||||||
|____//____ >|___ /
|
|
||||||
\/ \/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user