--- /dev/null
+# Declare files that will always have CRLF line endings on checkout.
+*.inf text eol=crlf
+
+# Declare pathc and diff files allow trailing whitespace
+*.diff text=auto -whitespace
+*.patch text=auto -whitespace
+
+# ignore .git
+.git* text export-ignore
--- /dev/null
+This is the README file for USBasp.
+
+USBasp is a USB in-circuit programmer for Atmel AVR controllers. It simply
+consists of an ATMega8 and a couple of passive components. The programmer
+uses a firmware-only USB driver, no special USB controller is needed.
+
+Features:
+- Works under multiple platforms. Linux, Mac OS X and Windows are tested.
+- No special controllers or smd components are needed.
+- Programming speed is up to 5kBytes/sec.
+- SCK option to support targets with low clock speed (< 1,5MHz).
+- Planned: serial interface to target (e.g. for debugging).
+
+
+LICENSE
+
+The project is built with AVR USB driver by Objective Development, which is
+published under a proprietary Open Source license. To conform with this
+license, USBasp is distributed under the same license conditions. See the
+file "firmware/usbdrv/License.txt" for details.
+
+
+LIMITATIONS
+
+Hardware:
+"circuit/usbasp_5V_circuit.pdf" shows a simple circuit. It doesn't meet the
+voltage range on the data lines specified in USB 1.1. Also this circuit can
+only be used for programming 5V target systems. For other systems a level
+converter is needed.
+
+Firmware:
+The firmware dosn't support USB Suspend Mode. A bidirectional serial
+interface to slave exists in hardware but the firmware doesn't support it yet.
+
+
+USE PRECOMPILED VERSION
+
+Firmware:
+Flash "bin/firmware/usbasp.xxxx-xx-xx.hex" to the ATMega8 with a working
+programmer (e.g. with avrdude, uisp, ...). Set jumper J2 to activate
+USBasp firmware update function.
+
+Windows:
+Start Windows and connect USBasp to the system. When Windows asks for a
+driver, choose "bin/win-driver". On Win2k and WinXP systems, Windows will
+warn that the driver is is not 'digitally signed'. Ignore this message and
+continue with the installation.
+Now you can run the precompiled version of avrdude: change in command line
+mode to "bin/win-avrdude" and start the program. Consult the documentation
+of avrdude for details. Examples:
+1. Enter terminal mode with an AT90S2313 connected to the programmer:
+ avrdude -c usbasp -p at90s2313 -t
+2. Write main.hex to the flash of an ATmega8:
+ avrdude -c usbasp -p atmega8 -U flash:w:main.hex
+
+Setting jumpers:
+J1 Power target
+ Supply target with 5V (USB voltage). Be careful with this option, the
+ circuit isn't protected against short circuit!
+J2 Jumper for firmware upgrade (not self-upgradable)
+ Set this jumper for flashing the ATMega8 of USBasp with another working
+ programmer.
+J3 SCK option
+ If the target clock is lower than 1,5 MHz, you have to set this jumper.
+ Then SCK is scaled down from 375 kHz to about 8 kHz.
+
+
+BUILDING AND INSTALLING FROM SOURCE CODE
+
+Firmware:
+To compile the firmware
+1. install the GNU toolchain for AVR microcontrollers (avr-gcc, avr-libc),
+2. change directory to firmware/
+3. run "make"
+4. flash "main.hex" to the ATMega8. E.g. with uisp or avrdude (check
+the Makefile option "make avrdude"). To flash the firmware you have
+to set jumper J2 and connect USBasp to a working programmer.
+
+Software (avrdude):
+An extension to avrdude (http://www.nongnu.org/avrdude/) was written.
+To compile the software:
+1. install libusb: http://libusb.sourceforge.net/
+2. get the csv version of avrdude:
+ export CVS_RSH="ssh"
+ cvs -z3 -d:ext:anoncvs@savannah.nongnu.org:/cvsroot/avrdude co avrdude
+3. cp usbasp/software/usbasp.* avrdude/
+4. cd avrdude
+5. apply the patch:
+ patch < ../usbasp/software/avrdude_usbasp.xxxx-xx-xx.patch
+6. configure to your environment:
+ ./bootstrap (I had to comment out the two if-blocks which verify the
+ installed versions of autoconf and automake)
+ ./configure
+7. compile and install it:
+ make
+ make install
+
+Notes on Windows (Cygwin):
+Download libusb-win32-device-bin-x.x.x.x.tar.gz from
+http://libusb-win32.sourceforge.net/ and unpack it.
+-> copy lib/gcc/libusb.a to lib-path
+-> copy include/usb.h to include-path
+cd avrdude
+./configure LDFLAGS="-static" --enable-versioned-doc=no
+make
+
+Notes on Darwin/MacOS X:
+after "./configure" I had to edit Makefile:
+change "avrdude_CPPFLAGS" to "AM_CPPFLAGS"
+(why is this needed only on mac? bug in configure.ac?)
+
+
+FILES IN THE DISTRIBUTION
+
+Readme.txt ...................... The file you are currently reading
+firmware ........................ Source code of the controller firmware
+firmware/usbdrv ................. AVR USB driver by Objective Development
+firmware/usbdrv/License.txt ..... Public license for AVR USB driver and USBasp
+software ........................ Source code of the host software
+circuit ......................... Circuit diagram in PDF
+bin ............................. Precompiled programs
+bin/win-driver .................. Windows driver
+bin/win-avrdude ................. avrdude compiled for Windows
+
+
+MORE INFORMATION
+
+For more information on USBasp and it's components please visit the
+following URLs:
+
+USBasp .......................... http://www.fischl.de/usbasp/
+
+Firmware-only AVR USB driver .... http://www.obdev.at/products/avrusb/
+avrdude ......................... http://www.nongnu.org/avrdude/
+libusb .......................... http://libusb.sourceforge.net/
+libusb-win32 .................... http://libusb-win32.sourceforge.net/
+
+
+2005-04-21 Thomas Fischl <tfischl@gmx.de>
+http://www.fischl.de
--- /dev/null
+:100000003BC072C153C052C051C050C04FC04EC05F
+:100010004DC04CC04BC04AC049C048C047C046C094
+:1000200045C044C043C00E03550053004200610068
+:10003000730070001C037700770077002E006600C5
+:1000400069007300630068006C002E00610074009A
+:1000500004030904090212000101008019090400C7
+:1000600000000000000012010101FF000008EB0386
+:10007000B4C700010102000111241FBECFE5D4E086
+:10008000DEBFCDBF10E0A0E6B0E0EAE9FCE002C0D0
+:1000900005900D92A436B107D9F710E0A4E6B0E0C0
+:1000A00001C01D92A23AB107E1F7E2C5A9CF1F93A3
+:1000B000CF93FC0180919B008D3269F080917A0092
+:1000C00087FD04C0CF0145D58F3F71F010926300CA
+:1000D00010927A0066C0C0E010E8683061F0C0930A
+:1000E000630010937A005DC08EE180938D0082E002
+:1000F0008093620056C080818076F9F426E930E072
+:10010000C093960081818823A1F08530E9F0863084
+:10011000F9F0883061F18A3071F130939D002093BD
+:100120009C0087818823D9F686818C17C0F6C82F5A
+:10013000D6CFC0939700C2E0F0CFC681CF01FCD3E9
+:100140008F3FA9F710E0CBCF828180937B00E5CF72
+:1001500010EC8381813089F0823099F08330E9F6A8
+:100160008281882391F4C4E020E530E0D6CFC1E05D
+:10017000C0939600D2CFC1E0D0CFC2E126E630E0F6
+:10018000CCCFC2E124E530E0C8CF813031F08230FD
+:1001900021F6CEE026E230E0C0CFCCE124E330E02F
+:1001A000BCCFCF911F910895CF9360919E0066239D
+:1001B00051F0635067FD05C0809199009927019621
+:1001C00076DF10929E008091620087FD1AC086B390
+:1001D000837019F010927C0077C080917C00882396
+:1001E00009F072C094E686B3837009F06DC0915037
+:1001F000D1F781E080937C009093980090937B00EE
+:1002000063C0809163008F3F31F12BE490917A00BD
+:1002100090FD23EC9F5F90937A0020938D00682FD0
+:10022000893008F068E0861B80936300AEE8B0E098
+:1002300097FD30C0662349F560E070E0C62F693055
+:10024000A0F08EE180938D0092E08FEF80936300A9
+:1002500090936200BCCF80917B00882309F4B7CFD4
+:100260008093980010927B00B2CF8EE890E0B9D1D5
+:10027000EC2FFF27E357FF4F818392839C2F9C5FD6
+:10028000C83018F390936200A2CFCD0125D4682F17
+:100290007727D4CFE0919C00F0919D0096FF0DC090
+:1002A000962F03C084918D9331969150D8F7F09397
+:1002B0009D00E0939C007727C1CF962F02C08191CB
+:1002C0008D939150E0F7F3CFCF91089584E690E0BD
+:1002D00080939A000B968093990085B7836085BFC1
+:1002E0008BB780648BBF08950F930FB70F9305E012
+:1002F000B09BFECF0A95B099E9F71F933F932F93D8
+:1003000031E012E006B3102710FD32E0102F3A95CD
+:10031000C9F700FDE0C006B3102717952FE7279512
+:10032000DF9316B3012707952795CF93C0919A00C5
+:1003300006B31027179527953BE0DD274F9316B39B
+:100340000127079527954FEF000051C005E0B09BAE
+:10035000FECF0A95B099E9F7DF9100C0D1CF16B36F
+:10036000137079F1407C2C6F13C006B3037049F110
+:1003700041782C6F15C0037021F1102F2C6F06B33C
+:1003800019C006B30370E9F04E7F2C6F18C038F324
+:1003900006B30370B1F0102717952795243028F382
+:1003A00016B3012707952795422749934FEF06B3C8
+:1003B000243008F3102717952795243010F316B32F
+:1003C0001370E1F10127079527952430F0F006B36B
+:1003D0000370A1F11027179527952430E0F016B38C
+:1003E0000127079527953A9541F12430D0F006B3BF
+:1003F000037021F11027179527952430C0F016B30C
+:100400000127079527952430C2CF16B31370B1F09A
+:100410004C7F2C6FDCCF06B3037081F0487F2C6FCC
+:10042000DECF16B3137051F0407F2C6FE0CF06B3D0
+:10043000037021F0407E2C6FE2CF3AC03C2FC09178
+:100440009A003C1B00E433300ABF90F10881198107
+:10045000412F1F77209198000D3271F1013E61F11B
+:100460000936B9F0033C11F00B3411F510919F00DF
+:100470001123F1F000919E000030B1F530939E0001
+:1004800010939B0000919900C093990000939A00EB
+:100490002EC0121769F4309162003F3F29F10FEF2F
+:1004A00000936200CDE8D0E025C0002700939F00B4
+:1004B0004F91CF91DF910FC01217B9F700939F00B2
+:1004C0000FEF00936300009362004F91CF910AB742
+:1004D00006FD3CCFDF9100E40ABF2F913F911F91B1
+:1004E0000F910FBF0F911895C0E6D0E002C0C1E692
+:1004F000D0E032E05F9308B30C7F016008BB53E0AB
+:1005000017B3136017BB20E80FC0052710E008BB26
+:1005100010C0052710E0089408BB13C0052710E0A1
+:1005200015C0052710E019C020FF052708BB279537
+:1005300017951C3F50F720FF0527279508BB1795F7
+:100540001C3F38F720FF05272795179508BB1C3F50
+:1005500028F720FF0527279517951C3F08BB08F7AC
+:1005600000C0499120FF052708BB279517951C3F20
+:1005700048F520FF0527279508BB17951C3F30F548
+:1005800020FF05272795179508BB1C3F20F520FF66
+:100590000527279517951C3F08BB00F5242F3A9592
+:1005A00019F60C7F5F9108BB34E03A95F1F70160D2
+:1005B00017B31C7F08BB0C7F4F91CF9117BB08BBB3
+:1005C000DF9189CF052710E008BBD1CF052710E0C8
+:1005D000089408BBD4CF052710E0D6CF052710E03C
+:1005E000DACFA82FB92F8FEF9FEF41E050EA61508B
+:1005F00070F02D9138E0722F782796958795269583
+:1006000070FF02C0842795273A95A9F7F0CF80950F
+:100610009095089582E58DB981E08EB9089588237B
+:1006200039F480E493E09093A1008093A0000895B2
+:100630008DE593E09093A1008093A000089592B778
+:1006400082B7891B8C30E0F3089587B38C6287BB37
+:10065000C298C598F4DFC29AF2DFC2988091A000D8
+:100660009091A1008D55934009F00895D3DF08952E
+:1006700087B3837D87BB88B3837D88BB1DB808950E
+:100680000F931F93CF93C82F00E017E00CC0C398BF
+:10069000CC0F000FB4990F5FC59AD1DFC598CFDF9B
+:1006A000115017FD04C0C7FFF2CFC39AF1CF802FBE
+:1006B0009927CF911F910F9108958FB9779BFECF06
+:1006C0008FB1992708951F93CF93CFE103C0C150F5
+:1006D000CF3F51F1E091A000F091A1008CEA099583
+:1006E000E091A000F091A10083E50995E091A000C0
+:1006F000F091A10080E00995182FE091A000F09101
+:10070000A10080E00995133591F01DB8C59A97DFD7
+:10071000C59895DF8091A0009091A1008D559340E0
+:10072000B1F678DFC150B0F681E090E002C080E021
+:1007300090E0CF911F9108950F931F938C018170CA
+:10074000880F880F880FE091A000F091A1008062CF
+:100750000995C801892F99278695E091A000F0910D
+:10076000A100099516950795E091A000F091A100D0
+:10077000802F0995E091A000F091A10080E00995FB
+:1007800099271F910F9108950F931F93CF93DF9394
+:10079000EC01062F142F8170880F880F880FE091CD
+:1007A000A000F091A10080640995CE01892F9927BE
+:1007B0008695E091A000F091A1000995CE01969553
+:1007C0008795E091A000F091A1000995E091A0002B
+:1007D000F091A100802F09951123A9F00F3789F01E
+:1007E0001EE102B7CE01A8DF8F3769F482B7801B04
+:1007F0008D3310F002B711501123A1F781E090E082
+:1008000004C08FE08CD080E090E0DF91CF911F9109
+:100810000F9108950F931F93CF93DF93EC01162F41
+:10082000E091A000F091A1008CE40995CE01892F00
+:1008300099278695E091A000F091A1000995CE013D
+:1008400096958795E091A000F091A1000995E0911F
+:10085000A000F091A10080E009951F3F89F01EE102
+:1008600002B7CE0169DF8F3F69F482B7801B8D33F9
+:1008700010F002B711501123A1F781E090E004C0FD
+:100880008FE04DD080E090E0DF91CF911F910F91EC
+:1008900008950F931F938C01E091A000F091A100A7
+:1008A00080EA0995812F9927E091A000F091A1009D
+:1008B0000995E091A000F091A100802F0995E091A9
+:1008C000A000F091A10080E0099599271F910F9158
+:1008D0000895FF920F931F938C01F62EE091A000D4
+:1008E000F091A10080EC0995812F9927E091A0005B
+:1008F000F091A1000995E091A000F091A100802F56
+:100900000995E091A000F091A1008F2D09958EE14D
+:1009100006D080E090E01F910F91FF900895382F4E
+:1009200020E0231740F492B782B7891B8C33E0F3A1
+:100930002F5F2317C0F308951F93CF93DF93EC012C
+:1009400010E089818130A1F0823009F472C08330D7
+:1009500009F472C0843091F0873009F450C08530BA
+:1009600009F4AAC0863039F1883009F0A9C086C0E0
+:100970009A9B812F54DE69DEA998A2C08B819927AA
+:10098000982F88272A813327822B932B90938900D5
+:10099000809388008F819927982F88272E8133276D
+:1009A000822B932B90937E0080937D0082E0809336
+:1009B0007F001FEF85C08B819927982F88272A8178
+:1009C0003327822B932B90938900809388009C81FE
+:1009D00090938A008D8180938B0080FF02C090935A
+:1009E0008C008F819927982F88272E813327822B7F
+:1009F000932B90937E0080937D0081E0D8CF8B81F4
+:100A00009927982F88272A813327822B932B90931D
+:100A10008900809388008F819927982F88272E81BD
+:100A20003327822B932B90937E0080937D0083E06D
+:100A3000BECF1EDEA99A44C0E091A000F091A100B3
+:100A40008A81099580938000E091A000F091A10037
+:100A50008B81099580938100E091A000F091A10025
+:100A60008C81099580938200E091A000F091A10013
+:100A70008D8109958093830014E022C08B81992792
+:100A8000982F88272A813327822B932B90938900D4
+:100A90008093880010938A0010938B008F81992790
+:100AA000982F88272E813327822B932B90937E00BB
+:100AB00080937D0084E07BCF06DE8093800011E090
+:100AC00080E890E090939D0080939C00812F99276F
+:100AD000DF91CF911F910895EF92FF921F93CF93D3
+:100AE0007C01162F90917F00892F8250823050F523
+:100AF000C0E0C617C0F01FC08091880090918900A7
+:100B0000C8DEF701EC0FF11D808380918800909181
+:100B1000890001969093890080938800CF5FC11768
+:100B200050F490917F00923039F780918800909135
+:100B3000890002DEE6CF183010F410927F00812F7A
+:100B4000992702C08FEF90E0CF911F91FF90EF9017
+:100B50000895CF92DF92EF92FF920F931F93CF935E
+:100B6000DF936C01062F40917F00413019F0443033
+:100B700009F073C010E01017F0F16CC080918A008A
+:100B8000882309F046C0C12FDD27FE01EC0DFD1DB5
+:100B900060818091880090918900F6DD80917D00D0
+:100BA00090917E00019790937E0080937D00892B29
+:100BB000A1F410927F0080918B0081FF0EC0909174
+:100BC0008C0080918A00981741F0CC0DDD1D688162
+:100BD00080918800909189001DDE8091880090911D
+:100BE0008900019690938900809388001F5F1017F9
+:100BF00088F540917F00413009F2C12FDD27FE01C9
+:100C0000EC0DFD1D6081809188009091890061DE6E
+:100C1000C5CFC12FDD277E01EC0CFD1C40E0F701A4
+:100C200060818091880090918900AEDD80918C0078
+:100C3000815080938C00882309F0B0CFF701608148
+:100C40008091880090918900E5DD80918A008093F1
+:100C50008C00A4CF80E090E002C08FEF90E0DF91A5
+:100C6000CF911F910F91FF90EF90DF90CF9008955B
+:100C7000CFE5D4E0DEBFCDBF12BA18BA8BEF81BB8F
+:100C800017BA93E094BB8EEF85BB93BF81E0C7DCBE
+:0A0C90001DDB789489DA88DAFDCFC5
+:040C9A005AD2FFFF2C
+:00000001FF
--- /dev/null
+# $Id: avrdude.conf.in,v 1.36 2004/12/22 01:30:30 bdean Exp $
+#
+# AVRDUDE Configuration File
+#
+# This file contains configuration data used by AVRDUDE which describes
+# the programming hardware pinouts and also provides part definitions.
+# AVRDUDE's "-C" command line option specifies the location of the
+# configuration file. The "-c" option names the programmer configuration
+# which must match one of the entry's "id" parameter. The "-p" option
+# identifies which part AVRDUDE is going to be programming and must match
+# one of the parts' "id" parameter.
+#
+# Possible entry formats are:
+#
+# programmer
+# id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
+# desc = <description> ; # quoted string
+# type = par | stk500 | avr910; # programmer type
+# baudrate = <num> ; # baudrate for avr910-programmer
+# vcc = <num1> [, <num2> ... ] ; # pin number(s)
+# reset = <num> ; # pin number
+# sck = <num> ; # pin number
+# mosi = <num> ; # pin number
+# miso = <num> ; # pin number
+# errled = <num> ; # pin number
+# rdyled = <num> ; # pin number
+# pgmled = <num> ; # pin number
+# vfyled = <num> ; # pin number
+# ;
+#
+# part
+# id = <id> ; # quoted string
+# desc = <description> ; # quoted string
+# devicecode = <num> ; # deprecated, use stk500_devcode
+# stk500_devcode = <num> ; # numeric
+# avr910_devcode = <num> ; # numeric
+# chip_erase_delay = <num> ; # micro-seconds
+# pagel = <num> ; # pin name in hex, i.e., 0xD7
+# bs2 = <num> ; # pin name in hex, i.e., 0xA0
+# reset = dedicated | io;
+# retry_pulse = reset | sck;
+# pgm_enable = <instruction format> ;
+# chip_erase = <instruction format> ;
+# memory <memtype>
+# paged = <yes/no> ; # yes / no
+# size = <num> ; # bytes
+# page_size = <num> ; # bytes
+# num_pages = <num> ; # numeric
+# min_write_delay = <num> ; # micro-seconds
+# max_write_delay = <num> ; # micro-seconds
+# readback_p1 = <num> ; # byte value
+# readback_p2 = <num> ; # byte value
+# pwroff_after_write = <yes/no> ; # yes / no
+# read = <instruction format> ;
+# write = <instruction format> ;
+# read_lo = <instruction format> ;
+# read_hi = <instruction format> ;
+# write_lo = <instruction format> ;
+# write_hi = <instruction format> ;
+# loadpage_lo = <instruction format> ;
+# loadpage_hi = <instruction format> ;
+# writepage = <instruction format> ;
+# ;
+# ;
+#
+# If any of the above parameters are not specified, the default value
+# of 0 is used for numerics or the empty string ("") for string
+# values. If a required parameter is left empty, AVRDUDE will
+# complain.
+#
+# NOTES:
+# * 'devicecode' is the device code used by the STK500 (see codes
+# listed below)
+# * Not all memory types will implement all instructions.
+# * AVR Fuse bits and Lock bits are implemented as a type of memory.
+# * Example memory types are:
+# "flash", "eeprom", "fuse", "lfuse" (low fuse), "hfuse" (high
+# fuse), "signature", "calibration", "lock"
+# * The memory type specified on the avrdude command line must match
+# one of the memory types defined for the specified chip.
+# * The pwroff_after_write flag causes avrdude to attempt to
+# power the device off and back on after an unsuccessful write to
+# the affected memory area if VCC programmer pins are defined. If
+# VCC pins are not defined for the programmer, a message
+# indicating that the device needs a power-cycle is printed out.
+# This flag was added to work around a problem with the
+# at90s4433/2333's; see the at90s4433 errata at:
+#
+# http://www.atmel.com/atmel/acrobat/doc1280.pdf
+#
+# INSTRUCTION FORMATS
+#
+# Instruction formats are specified as a comma seperated list of
+# string values containing information (bit specifiers) about each
+# of the 32 bits of the instruction. Bit specifiers may be one of
+# the following formats:
+#
+# '1' = the bit is always set on input as well as output
+#
+# '0' = the bit is always clear on input as well as output
+#
+# 'x' = the bit is ignored on input and output
+#
+# 'a' = the bit is an address bit, the bit-number matches this bit
+# specifier's position within the current instruction byte
+#
+# 'aN' = the bit is the Nth address bit, bit-number = N, i.e., a12
+# is address bit 12 on input, a0 is address bit 0.
+#
+# 'i' = the bit is an input data bit
+#
+# 'o' = the bit is an output data bit
+#
+# Each instruction must be composed of 32 bit specifiers. The
+# instruction specification closely follows the instruction data
+# provided in Atmel's data sheets for their parts.
+#
+# See below for some examples.
+#
+#
+# The following are STK500 part device codes to use for the
+# "devicecode" field of the part. These came from Atmel's software
+# section avr061.zip which accompanies the application note
+# AVR061 available from:
+#
+# http://www.atmel.com/atmel/acrobat/doc2525.pdf
+#
+
+#define ATTINY10 0x10
+#define ATTINY11 0x11
+#define ATTINY12 0x12
+#define ATTINY15 0x13
+#define ATTINY13 0x14
+
+#define ATTINY22 0x20
+#define ATTINY26 0x21
+#define ATTINY28 0x22
+#define ATTINY2313 0x23
+
+#define AT90S1200 0x33
+
+#define AT90S2313 0x40
+#define AT90S2323 0x41
+#define AT90S2333 0x42
+#define AT90S2343 0x43
+
+#define AT90S4414 0x50
+#define AT90S4433 0x51
+#define AT90S4434 0x52
+#define ATMEGA48 0x59
+
+#define AT90S8515 0x60
+#define AT90S8535 0x61
+#define AT90C8534 0x62
+#define ATMEGA8515 0x63
+#define ATMEGA8535 0x64
+
+#define ATMEGA8 0x70
+#define ATMEGA88 0x73
+
+#define ATMEGA161 0x80
+#define ATMEGA163 0x81
+#define ATMEGA16 0x82
+#define ATMEGA162 0x83
+#define ATMEGA169 0x84
+
+#define ATMEGA323 0x90
+#define ATMEGA32 0x91
+
+#define ATMEGA64 0xA0
+
+#define ATMEGA103 0xB1
+#define ATMEGA128 0xB2
+#define AT90CAN128 0xB3
+
+#define AT86RF401 0xD0
+
+#define AT89START 0xE0
+#define AT89S51 0xE0
+#define AT89S52 0xE1
+
+
+#
+# Overall avrdude defaults
+#
+default_parallel = "/dev/parport0";
+default_serial = "/dev/ttyS0";
+
+
+#
+# PROGRAMMER DEFINITIONS
+#
+
+programmer
+ id = "bsd";
+ desc = "Brian Dean's Programmer, http://www.bsdhome.com/avrdude/";
+ type = par;
+ vcc = 2, 3, 4, 5;
+ reset = 7;
+ sck = 8;
+ mosi = 9;
+ miso = 10;
+;
+
+programmer
+ id = "avrisp";
+ desc = "Atmel AVR ISP";
+ type = stk500;
+;
+
+programmer
+ id = "usbasp";
+ desc = "usbasp";
+ type = usbasp;
+;
+
+programmer
+ id = "stk500";
+ desc = "Atmel STK500";
+ type = stk500;
+;
+
+programmer
+ id = "avr910";
+ desc = "Atmel Low Cost Serial Programmer";
+ type = avr910;
+;
+
+programmer
+ id = "butterfly";
+ desc = "Atmel Butterfly Development Board";
+ type = butterfly;
+;
+
+programmer
+ id = "pavr";
+ desc = "Jason Kyle's pAVR Serial Programmer";
+ type = avr910;
+;
+
+programmer
+ id = "stk200";
+ desc = "STK200";
+ type = par;
+ buff = 4, 5;
+ sck = 6;
+ mosi = 7;
+ reset = 9;
+ miso = 10;
+;
+
+# The programming dongle used by the popular Ponyprog
+# utility. It is almost similar to the STK200 one,
+# except that there is a LED indicating that the
+# programming is currently in progress.
+
+programmer
+ id = "pony-stk200";
+ desc = "Pony Prog STK200";
+ type = par;
+ buff = 4, 5;
+ sck = 6;
+ mosi = 7;
+ reset = 9;
+ miso = 10;
+ pgmled = 8;
+;
+
+programmer
+ id = "dt006";
+ desc = "Dontronics DT006";
+ type = par;
+ reset = 4;
+ sck = 5;
+ mosi = 2;
+ miso = 11;
+;
+
+programmer
+ id = "bascom";
+ desc = "Bascom SAMPLE programming cable";
+ type = par;
+ reset = 4;
+ sck = 5;
+ mosi = 2;
+ miso = 11;
+;
+
+programmer
+ id = "alf";
+ desc = "Nightshade ALF-PgmAVR, http://nightshade.homeip.net/";
+ type = par;
+ vcc = 2, 3, 4, 5;
+ buff = 6;
+ reset = 7;
+ sck = 8;
+ mosi = 9;
+ miso = 10;
+ errled = 1;
+ rdyled = 14;
+ pgmled = 16;
+ vfyled = 17;
+;
+
+programmer
+ id = "sp12";
+ desc = "Steve Bolt's Programmer";
+ type = par;
+ vcc = 4,5,6,7,8;
+ reset = 3;
+ sck = 2;
+ mosi = 9;
+ miso = 11;
+;
+
+programmer
+ id = "picoweb";
+ desc = "Picoweb Programming Cable, http://www.picoweb.net/";
+ type = par;
+ reset = 2;
+ sck = 3;
+ mosi = 4;
+ miso = 13;
+;
+
+programmer
+ id = "abcmini";
+ desc = "ABCmini Board, aka Dick Smith HOTCHIP";
+ type = par;
+ reset = 4;
+ sck = 3;
+ mosi = 2;
+ miso = 10;
+;
+
+programmer
+ id = "futurlec";
+ desc = "Futurlec.com programming cable.";
+ type = par;
+ reset = 3;
+ sck = 2;
+ mosi = 1;
+ miso = 10;
+;
+
+
+# From the contributor of the "xil" jtag cable:
+# The "vcc" definition isn't really vcc (the cable gets its power from
+# the programming circuit) but is necessary to switch one of the
+# buffer lines (trying to add it to the "buff" lines doesn't work).
+# With this, TMS connects to RESET, TDI to MOSI, TDO to MISO and TCK
+# to SCK (plus vcc/gnd of course)
+programmer
+ id = "xil";
+ desc = "Xilinx JTAG cable";
+ type = par;
+ mosi = 2;
+ sck = 3;
+ reset = 4;
+ buff = 5;
+ miso = 13;
+ vcc = 6;
+;
+
+
+#
+# PART DEFINITIONS
+#
+
+#------------------------------------------------------------
+# ATtiny12
+#------------------------------------------------------------
+
+part
+ id = "t12";
+ desc = "ATtiny12";
+ stk500_devcode = 0x12;
+ avr910_devcode = 0x55;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 64;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
+ ;
+
+ memory "flash"
+ size = 1024;
+ min_write_delay = 4500;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "fuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x",
+ "x x x x x x x x i i i i i i i i";
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny13
+#------------------------------------------------------------
+
+part
+ id = "t13";
+ desc = "ATtiny13";
+ stk500_devcode = 0x14;
+ chip_erase_delay = 4000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 64;
+ min_write_delay = 4000;
+ max_write_delay = 4000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 1024;
+ page_size = 32;
+ num_pages = 32;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 0 0 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 0 0 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 0 0 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+;
+
+
+#------------------------------------------------------------
+# ATtiny15
+#------------------------------------------------------------
+
+part
+ id = "t15";
+ desc = "ATtiny15";
+ stk500_devcode = 0x13;
+ avr910_devcode = 0x56;
+ chip_erase_delay = 8200;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 64;
+ min_write_delay = 8200;
+ max_write_delay = 8200;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
+ ;
+
+ memory "flash"
+ size = 1024;
+ min_write_delay = 4100;
+ max_write_delay = 4100;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "fuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o o o x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x",
+ "x x x x x x x x i i i i 1 1 i i";
+ ;
+;
+
+
+#------------------------------------------------------------
+# AT90s1200
+#------------------------------------------------------------
+
+part
+ id = "1200";
+ desc = "AT90S1200";
+ stk500_devcode = 0x33;
+ avr910_devcode = 0x13;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 64;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
+ ;
+ memory "flash"
+ size = 1024;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s4414
+#------------------------------------------------------------
+
+part
+ id = "4414";
+ desc = "AT90S4414";
+ stk500_devcode = 0x50;
+ avr910_devcode = 0x28;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 256;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x80;
+ readback_p2 = 0x7f;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+ ;
+ memory "flash"
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x7f;
+ readback_p2 = 0x7f;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s2313
+#------------------------------------------------------------
+
+part
+ id = "2313";
+ desc = "AT90S2313";
+ stk500_devcode = 0x40;
+ avr910_devcode = 0x20;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 128;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x80;
+ readback_p2 = 0x7f;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+ ;
+ memory "flash"
+ size = 2048;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x7f;
+ readback_p2 = 0x7f;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x i i x",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s2333
+#------------------------------------------------------------
+
+part
+ id = "2333";
+ desc = "AT90S2333";
+ stk500_devcode = 0x42;
+ avr910_devcode = 0x34;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 128;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+ ;
+ memory "flash"
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ pwroff_after_write = yes;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# AT90s2343
+#------------------------------------------------------------
+
+part
+ id = "2343";
+ desc = "AT90S2343";
+ stk500_devcode = 0x43;
+ avr910_devcode = 0x4c;
+ chip_erase_delay = 18000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 128;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+ ;
+ memory "flash"
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o o x x x x o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o o x x x x o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# AT90s4433
+#------------------------------------------------------------
+
+part
+ id = "4433";
+ desc = "AT90S4433";
+ stk500_devcode = 0x51;
+ avr910_devcode = 0x30;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 256;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+ ;
+ memory "flash"
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ pwroff_after_write = yes;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s4434
+#------------------------------------------------------------
+
+part
+ id = "4434";
+ desc = "AT90S4434";
+ stk500_devcode = 0x52;
+ avr910_devcode = 0x6c;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 256;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+ ;
+ memory "flash"
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s8515
+#------------------------------------------------------------
+
+part
+ id = "8515";
+ desc = "AT90S8515";
+ stk500_devcode = 0x60;
+ avr910_devcode = 0x38;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x80;
+ readback_p2 = 0x7f;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+ ;
+ memory "flash"
+ size = 8192;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x7f;
+ readback_p2 = 0x7f;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x x o";
+ write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o x x x x x x";
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s8535
+#------------------------------------------------------------
+
+part
+ id = "8535";
+ desc = "AT90S8535";
+ stk500_devcode = 0x61;
+ avr910_devcode = 0x68;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+ ;
+ memory "flash"
+ size = 8192;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x x o";
+ write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o x x x x x x";
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega103
+#------------------------------------------------------------
+
+part
+ id = "m103";
+ desc = "ATMEGA103";
+ stk500_devcode = 0xB1;
+ avr910_devcode = 0x41;
+ chip_erase_delay = 112000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 4096;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 22000;
+ max_write_delay = 56000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+ ;
+
+ memory "fuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x o x o 1 o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 1 i 1 i i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega64
+#------------------------------------------------------------
+
+part
+ id = "m64";
+ desc = "ATMEGA64";
+ stk500_devcode = 0xA0;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+
+
+#------------------------------------------------------------
+# ATmega128
+#------------------------------------------------------------
+
+part
+ id = "m128";
+ desc = "ATMEGA128";
+ stk500_devcode = 0xB2;
+ avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90CAN128
+#------------------------------------------------------------
+
+part
+ id = "c128";
+ desc = "AT90CAN128";
+ stk500_devcode = 0xB3;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega16
+#------------------------------------------------------------
+
+part
+ id = "m16";
+ desc = "ATMEGA16";
+ stk500_devcode = 0x82;
+ avr910_devcode = 0x74;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega162
+#------------------------------------------------------------
+
+part
+ id = "m162";
+ desc = "ATMEGA162";
+ stk500_devcode = 0x83;
+ chip_erase_delay = 9000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+ ;
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x 1 1 1 i i i i 1";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+
+ read = "0 0 1 1 0 0 0 0 0 0 x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+;
+
+
+
+#------------------------------------------------------------
+# ATmega163
+#------------------------------------------------------------
+
+part
+ id = "m163";
+ desc = "ATMEGA163";
+ stk500_devcode = 0x81;
+ avr910_devcode = 0x64;
+ chip_erase_delay = 32000;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 4000;
+ max_write_delay = 4000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o x x o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i 1 1 i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x x x x x 1 o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x 0 x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega169
+#------------------------------------------------------------
+
+part
+ id = "m169";
+ desc = "ATMEGA169";
+ stk500_devcode = 0x85;
+ avr910_devcode = 0x75;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i x";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega32
+#------------------------------------------------------------
+
+part
+ id = "m32";
+ desc = "ATMEGA32";
+ stk500_devcode = 0x91;
+ avr910_devcode = 0x72;
+ chip_erase_delay = 9000;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega161
+#------------------------------------------------------------
+
+part
+ id = "m161";
+ desc = "ATMEGA161";
+ stk500_devcode = 0x80;
+ avr910_devcode = 0x60;
+ chip_erase_delay = 28000;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 3400;
+ max_write_delay = 3400;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 14000;
+ max_write_delay = 14000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+ ;
+
+ memory "fuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x o x o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x",
+ "x x x x x x x x 1 i 1 i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega8
+#------------------------------------------------------------
+
+part
+ id = "m8";
+ desc = "ATMEGA8";
+ stk500_devcode = 0x70;
+ avr910_devcode = 0x76;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+
+#------------------------------------------------------------
+# ATmega8515
+#------------------------------------------------------------
+
+part
+ id = "m8515";
+ desc = "ATMEGA8515";
+ stk500_devcode = 0x63;
+ avr910_devcode = 0x3A;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+
+
+#------------------------------------------------------------
+# ATmega8535
+#------------------------------------------------------------
+
+part
+ id = "m8535";
+ desc = "ATMEGA8535";
+ stk500_devcode = 0x64;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATtiny26
+#------------------------------------------------------------
+
+part
+ id = "t26";
+ desc = "ATTINY26";
+ stk500_devcode = 0x21;
+ avr910_devcode = 0x5e;
+ pagel = 0xb3;
+ bs2 = 0xb2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 128;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 2048;
+ page_size = 32;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x x x x i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x x x x o o o o o";
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+;
+
+
+#------------------------------------------------------------
+# ATmega48
+#------------------------------------------------------------
+
+part
+ id = "m48";
+ desc = "ATMEGA48";
+ stk500_devcode = 0x59;
+# avr910_devcode = 0x;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 256;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega88
+#------------------------------------------------------------
+
+part
+ id = "m88";
+ desc = "ATMEGA88";
+ stk500_devcode = 0x73;
+# avr910_devcode = 0x;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATtiny2313
+#------------------------------------------------------------
+
+part
+ id = "t2313";
+ desc = "ATtiny2313";
+ stk500_devcode = 0x23;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ pagel = 0xD4;
+ bs2 = 0xD6;
+ reset = io;
+ chip_erase_delay = 9000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 128;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+ ;
+ memory "flash"
+ paged = yes;
+ size = 2048;
+ page_size = 32;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+# The information in the data sheet of April/2004 is wrong, this works:
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+# The information in the data sheet of April/2004 is wrong, this works:
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+# The information in the data sheet of April/2004 is wrong, this works:
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+ ;
+# ATtiny2313 has Signature Bytes: 0x1E 0x91 0x0A.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+# The Tiny2313 has calibration data for both 4 MHz and 8 MHz.
+# The information in the data sheet of April/2004 is wrong, this works:
+
+ memory "calibration"
+ size = 2;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
--- /dev/null
+[Version]
+Signature = "$Chicago$"
+provider = %manufacturer%
+DriverVer = 03/09/2005,0.1.10.1
+CatalogFile = usbasp.cat
+
+Class = LibUsbDevices
+ClassGUID = {EB781AAF-9C70-4523-A5DF-642A87ECA567}
+
+[ClassInstall]
+AddReg=ClassInstall.AddReg
+
+[ClassInstall32]
+AddReg=ClassInstall.AddReg
+
+[ClassInstall.AddReg]
+HKR,,,,"LibUSB-Win32 Devices"
+HKR,,Icon,,"-20"
+
+[Manufacturer]
+%manufacturer%=Devices
+
+;--------------------------------------------------------------------------
+; Files
+;--------------------------------------------------------------------------
+
+[SourceDisksNames]
+1 = "Libusb-Win32 Driver Installation Disk",,
+
+[SourceDisksFiles]
+libusb0.sys = 1,,
+libusb0.dll = 1,,
+
+[DestinationDirs]
+LIBUSB.Files.Sys = 10,System32\Drivers
+LIBUSB.Files.Dll = 10,System32
+
+[LIBUSB.Files.Sys]
+libusb0.sys
+
+[LIBUSB.Files.Dll]
+libusb0.dll
+
+;--------------------------------------------------------------------------
+; Device driver
+;--------------------------------------------------------------------------
+
+[LIBUSB_DEV]
+CopyFiles = LIBUSB.Files.Sys, LIBUSB.Files.Dll
+AddReg = LIBUSB_DEV.AddReg
+
+[LIBUSB_DEV.NT]
+CopyFiles = LIBUSB.Files.Sys, LIBUSB.Files.Dll
+
+[LIBUSB_DEV.HW]
+DelReg = LIBUSB_DEV.DelReg.HW
+
+[LIBUSB_DEV.NT.HW]
+DelReg = LIBUSB_DEV.DelReg.HW
+
+[LIBUSB_DEV.NT.Services]
+AddService = libusb0, 0x00000002, LIBUSB.AddService
+
+[LIBUSB_DEV.AddReg]
+HKR,,DevLoader,,*ntkern
+HKR,,NTMPDriver,,libusb0.sys
+
+[LIBUSB_DEV.DelReg.HW]
+HKR,,"LowerFilters"
+
+;--------------------------------------------------------------------------
+; Services
+;--------------------------------------------------------------------------
+
+[LIBUSB.AddService]
+DisplayName = "LibUsb-Win32 - Kernel Driver 03/09/2005, 0.1.10.1"
+ServiceType = 1
+StartType = 3
+ErrorControl = 0
+ServiceBinary = %12%\libusb0.sys
+
+;--------------------------------------------------------------------------
+; Devices
+;--------------------------------------------------------------------------
+
+[Devices]
+"USBasp"=LIBUSB_DEV, USB\VID_03eb&PID_c7b4
+
+[Strings]
+manufacturer = "www.fischl.de"
--- /dev/null
+SERIAL = `echo /dev/tty.USA19QI*`
+UISP = uisp -dprog=avr910 -dserial=$(SERIAL) -dpart=auto
+TARGET = atmega8
+#TARGET = at90s2313
+# The two lines above are for "uisp" and the AVR910 serial programmer connected
+# to a Keyspan USB to serial converter to a Mac running Mac OS X.
+# Choose your favorite programmer and interface.
+
+COMPILE = avr-gcc -Wall -O2 -Iusbdrv -I. -mmcu=$(TARGET) # -DDEBUG_LEVEL=2
+
+OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o isp.o clock.o main.o
+
+
+# symbolic targets:
+all: main.hex
+
+.c.o:
+ $(COMPILE) -c $< -o $@
+#-Wa,-ahlms=$<.lst
+
+.S.o:
+ $(COMPILE) -x assembler-with-cpp -c $< -o $@
+# "-x assembler-with-cpp" should not be necessary since this is the default
+# file type for the .S (with capital S) extension. However, upper case
+# characters are not always preserved on Windows. To ensure WinAVR
+# compatibility define the file type manually.
+
+.c.s:
+ $(COMPILE) -S $< -o $@
+
+clean:
+ rm -f main.hex main.lst main.obj main.cof main.list main.map main.eep.hex main.bin *.o main.s usbdrv.s
+
+# file targets:
+main.bin: $(OBJECTS)
+ $(COMPILE) -o main.bin $(OBJECTS) -Wl,-Map,main.map
+
+main.hex: main.bin
+ rm -f main.hex main.eep.hex
+ avr-objcopy -j .text -j .data -O ihex main.bin main.hex
+# ./checksize main.bin
+# do the checksize script as our last action to allow successful compilation
+# on Windows with WinAVR where the Unix commands will fail.
+
+disasm: main.bin
+ avr-objdump -d main.bin
+
+cpp:
+ $(COMPILE) -E main.c
+
+avrdude:
+ avrdude -c butterfly -p $(TARGET) -U flash:w:main.hex
+
+uisp: all
+ $(UISP) --erase
+ $(UISP) --upload --verify if=main.hex
--- /dev/null
+/*
+ clock.c - part of USBasp
+
+ Autor..........: Thomas Fischl <tfischl@gmx.de>
+ Description....: Provides functions for timing/waiting
+ Licence........: Free under certain conditions. See Documentation.
+ Creation Date..: 2005-02-23
+ Last change....: 2005-04-20
+*/
+
+#include <inttypes.h>
+#include <avr/io.h>
+#include "clock.h"
+
+/* wait time * 320 us */
+void clockWait(uint8_t time) {
+
+ uint8_t i;
+ for (i = 0; i < time; i++) {
+ uint8_t starttime = TIMERVALUE;
+ while ((uint8_t) (TIMERVALUE - starttime) < CLOCK_T_320us) {}
+ }
+}
--- /dev/null
+/*
+ clock.h - part of USBasp
+
+ Autor..........: Thomas Fischl <tfischl@gmx.de>
+ Description....: Provides functions for timing/waiting
+ Licence........: Free under certain conditions. See Documentation.
+ Creation Date..: 2005-02-23
+ Last change....: 2005-04-20
+*/
+
+#ifndef __clock_h_included__
+#define __clock_h_included__
+
+#define F_CPU 12000000L /* 12MHz */
+#define TIMERVALUE TCNT0
+#define CLOCK_T_320us 60
+
+/* set prescaler to 64 */
+#define clockInit() TCCR0 = (1 << CS01) | (1 << CS00);
+
+/* wait time * 320 us */
+void clockWait(uint8_t time);
+
+#endif /* __clock_h_included__ */
--- /dev/null
+/*
+ isp.c - part of USBasp
+
+ Autor..........: Thomas Fischl <tfischl@gmx.de>
+ Description....: Provides functions for communication/programming
+ over ISP interface
+ Licence........: Free under certain conditions. See Documentation.
+ Creation Date..: 2005-02-23
+ Last change....: 2005-04-20
+*/
+
+#include <avr/io.h>
+#include "isp.h"
+#include "clock.h"
+
+#define spiHWdisable() SPCR = 0
+
+void spiHWenable() {
+
+ /* enable SPI, master, 375kHz SCK */
+ SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1);
+ SPSR = (1 << SPI2X);
+}
+
+void ispSetSCKOption(uchar option) {
+
+ if (option == 0) {
+
+ /* use software spi */
+ ispTransmit = ispTransmit_sw;
+ // spiHWdisable();
+
+ } else {
+
+ /* use hardware spi */
+ ispTransmit = ispTransmit_hw;
+
+ }
+}
+
+void ispDelay() {
+
+ uint8_t starttime = TIMERVALUE;
+ while ((uint8_t) (TIMERVALUE - starttime) < 12) { }
+}
+
+void ispConnect() {
+
+ /* all ISP pins are inputs before */
+ /* now set output pins */
+ ISP_DDR |= (1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI);
+
+ /* reset device */
+ ISP_OUT &= ~(1 << ISP_RST); /* RST low */
+ ISP_OUT &= ~(1 << ISP_SCK); /* SCK low */
+
+ /* positive reset pulse > 2 SCK (target) */
+ ispDelay();
+ ISP_OUT |= (1 << ISP_RST); /* RST high */
+ ispDelay();
+ ISP_OUT &= ~(1 << ISP_RST); /* RST low */
+
+ if (ispTransmit == ispTransmit_hw) {
+ spiHWenable();
+ }
+}
+
+void ispDisconnect() {
+
+ /* set all ISP pins inputs */
+ ISP_DDR &= ~((1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI));
+ /* switch pullups off */
+ ISP_OUT &= ~((1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI));
+
+ /* disable hardware SPI */
+ spiHWdisable();
+}
+
+uchar ispTransmit_sw(uchar send_byte) {
+
+ uchar rec_byte = 0;
+ uchar i;
+ for (i = 0; i < 8; i++) {
+
+ /* set MSB to MOSI-pin */
+ if ((send_byte & 0x80) != 0) {
+ ISP_OUT |= (1 << ISP_MOSI); /* MOSI high */
+ } else {
+ ISP_OUT &= ~(1 << ISP_MOSI); /* MOSI low */
+ }
+ /* shift to next bit */
+ send_byte = send_byte << 1;
+
+ /* receive data */
+ rec_byte = rec_byte << 1;
+ if ((ISP_IN & (1 << ISP_MISO)) != 0) {
+ rec_byte++;
+ }
+
+ /* pulse SCK */
+ ISP_OUT |= (1 << ISP_SCK); /* SCK high */
+ ispDelay();
+ ISP_OUT &= ~(1 << ISP_SCK); /* SCK low */
+ ispDelay();
+ }
+
+ return rec_byte;
+}
+
+uchar ispTransmit_hw(uchar send_byte) {
+ SPDR = send_byte;
+
+ while (!(SPSR & (1 << SPIF)));
+ return SPDR;
+}
+
+uchar ispEnterProgrammingMode() {
+ uchar check;
+ uchar count = 32;
+
+ while (count--) {
+ ispTransmit(0xAC);
+ ispTransmit(0x53);
+ check = ispTransmit(0);
+ ispTransmit(0);
+
+ if (check == 0x53) {
+ return 0;
+ }
+
+ spiHWdisable();
+
+ /* pulse SCK */
+ ISP_OUT |= (1 << ISP_SCK); /* SCK high */
+ ispDelay();
+ ISP_OUT &= ~(1 << ISP_SCK); /* SCK low */
+ ispDelay();
+
+ if (ispTransmit == ispTransmit_hw) {
+ spiHWenable();
+ }
+
+ }
+
+ return 1; /* error: device dosn't answer */
+}
+
+uchar ispReadFlash(unsigned int address) {
+ ispTransmit(0x20 | ((address & 1) << 3));
+ ispTransmit(address >> 9);
+ ispTransmit(address >> 1);
+ return ispTransmit(0);
+}
+
+
+uchar ispWriteFlash(unsigned int address, uchar data, uchar pollmode) {
+
+ /* 0xFF is value after chip erase, so skip programming
+ if (data == 0xFF) {
+ return 0;
+ }
+ */
+
+ ispTransmit(0x40 | ((address & 1) << 3));
+ ispTransmit(address >> 9);
+ ispTransmit(address >> 1);
+ ispTransmit(data);
+
+ if (pollmode == 0)
+ return 0;
+
+ if (data == 0x7F) {
+ clockWait(15); /* wait 4,8 ms */
+ return 0;
+ } else {
+
+ /* polling flash */
+ uchar retries = 30;
+ uint8_t starttime = TIMERVALUE;
+ while (retries != 0) {
+ if (ispReadFlash(address) != 0x7F) {
+ return 0;
+ };
+
+ if ((uint8_t) (TIMERVALUE - starttime) > CLOCK_T_320us) {
+ starttime = TIMERVALUE;
+ retries --;
+ }
+
+ }
+ return 1; /* error */
+ }
+
+}
+
+
+uchar ispFlushPage(unsigned int address, uchar pollvalue) {
+ ispTransmit(0x4C);
+ ispTransmit(address >> 9);
+ ispTransmit(address >> 1);
+ ispTransmit(0);
+
+
+ if (pollvalue == 0xFF) {
+ clockWait(15);
+ return 0;
+ } else {
+
+ /* polling flash */
+ uchar retries = 30;
+ uint8_t starttime = TIMERVALUE;
+
+ while (retries != 0) {
+ if (ispReadFlash(address) != 0xFF) {
+ return 0;
+ };
+
+ if ((uint8_t) (TIMERVALUE - starttime) > CLOCK_T_320us) {
+ starttime = TIMERVALUE;
+ retries --;
+ }
+
+ }
+
+ return 1; /* error */
+ }
+
+}
+
+
+uchar ispReadEEPROM(unsigned int address) {
+ ispTransmit(0xA0);
+ ispTransmit(address >> 8);
+ ispTransmit(address);
+ return ispTransmit(0);
+}
+
+
+uchar ispWriteEEPROM(unsigned int address, uchar data) {
+
+ ispTransmit(0xC0);
+ ispTransmit(address >> 8);
+ ispTransmit(address);
+ ispTransmit(data);
+
+ clockWait(30); // wait 9,6 ms
+
+ return 0;
+ /*
+ if (data == 0xFF) {
+ clockWait(30); // wait 9,6 ms
+ return 0;
+ } else {
+
+ // polling eeprom
+ uchar retries = 30; // about 9,6 ms
+ uint8_t starttime = TIMERVALUE;
+
+ while (retries != 0) {
+ if (ispReadEEPROM(address) != 0xFF) {
+ return 0;
+ };
+
+ if ((uint8_t) (TIMERVALUE - starttime) > CLOCK_T_320us) {
+ starttime = TIMERVALUE;
+ retries --;
+ }
+
+ }
+ return 1; // error
+ }
+ */
+
+}
--- /dev/null
+/*
+ isp.h - part of USBasp
+
+ Autor..........: Thomas Fischl <tfischl@gmx.de>
+ Description....: Provides functions for communication/programming
+ over ISP interface
+ Licence........: Free under certain conditions. See Documentation.
+ Creation Date..: 2005-02-23
+ Last change....: 2005-04-20
+*/
+
+#ifndef __isp_h_included__
+#define __isp_h_included__
+
+#ifndef uchar
+#define uchar unsigned char
+#endif
+
+#define ISP_OUT PORTB
+#define ISP_IN PINB
+#define ISP_DDR DDRB
+#define ISP_RST PB2
+#define ISP_MOSI PB3
+#define ISP_MISO PB4
+#define ISP_SCK PB5
+
+#define ISP_DELAY 1
+#define ISP_SCK_SLOW 0
+#define ISP_SCK_FAST 1
+
+/* Prepare connection to target device */
+void ispConnect();
+
+/* Close connection to target device */
+void ispDisconnect();
+
+/* read an write a byte from isp using software (slow) */
+uchar ispTransmit_sw(uchar send_byte);
+
+/* read an write a byte from isp using hardware (fast) */
+uchar ispTransmit_hw(uchar send_byte);
+
+/* enter programming mode */
+uchar ispEnterProgrammingMode();
+
+/* read byte from eeprom at given address */
+uchar ispReadEEPROM(unsigned int address);
+
+/* write byte to flash at given address */
+uchar ispWriteFlash(unsigned int address, uchar data, uchar pollmode);
+
+uchar ispFlushPage(unsigned int address, uchar pollvalue);
+
+/* read byte from flash at given address */
+uchar ispReadFlash(unsigned int address);
+
+/* write byte to eeprom at given address */
+uchar ispWriteEEPROM(unsigned int address, uchar data);
+
+/* pointer to sw or hw transmit function */
+uchar (*ispTransmit)(uchar);
+
+/* set SCK speed. call before ispConnect! */
+void ispSetSCKOption(uchar sckoption);
+
+#endif /* __isp_h_included__ */
--- /dev/null
+/*
+ USBasp - USB in-circuit programmer for Atmel AVR controllers
+
+ Thomas Fischl <tfischl@gmx.de>
+
+ License:
+ The project is built with AVR USB driver by Objective Development, which is
+ published under an own licence based on the GNU General Public License (GPL).
+ USBasp is also distributed under this enhanced licence. See Documentation.
+
+ Target.........: ATMega8 at 12 MHz
+ Creation Date..: 2005-02-20
+ Last change....: 2005-04-20
+
+ PC2 SCK speed option. GND -> slow (8khz SCK),
+ open -> fast (375kHz SCK)
+*/
+
+#include <avr/io.h>
+#include <avr/signal.h>
+#include <avr/interrupt.h>
+#include <avr/pgmspace.h>
+#include <avr/wdt.h>
+
+#include "usbdrv.h"
+#include "isp.h"
+#include "clock.h"
+
+#define USBASP_FUNC_CONNECT 1
+#define USBASP_FUNC_DISCONNECT 2
+#define USBASP_FUNC_TRANSMIT 3
+#define USBASP_FUNC_READFLASH 4
+#define USBASP_FUNC_ENABLEPROG 5
+#define USBASP_FUNC_WRITEFLASH 6
+#define USBASP_FUNC_READEEPROM 7
+#define USBASP_FUNC_WRITEEEPROM 8
+
+#define PROG_STATE_IDLE 0
+#define PROG_STATE_WRITEFLASH 1
+#define PROG_STATE_READFLASH 2
+#define PROG_STATE_READEEPROM 3
+#define PROG_STATE_WRITEEEPROM 4
+
+#define PROG_BLOCKFLAG_FIRST 1
+#define PROG_BLOCKFLAG_LAST 2
+
+#define ledRedOn() PORTC &= ~(1 << PC1)
+#define ledRedOff() PORTC |= (1 << PC1)
+#define ledGreenOn() PORTC &= ~(1 << PC0)
+#define ledGreenOff() PORTC |= (1 << PC0)
+
+static uchar replyBuffer[8];
+
+static uchar prog_state = PROG_STATE_IDLE;
+
+static unsigned int prog_address;
+static unsigned int prog_nbytes = 0;
+static uchar prog_pagesize;
+static uchar prog_blockflags;
+static uchar prog_pagecounter;
+
+
+uchar usbFunctionSetup(uchar data[8]) {
+
+ uchar len = 0;
+
+ if(data[1] == USBASP_FUNC_CONNECT){
+
+ /* set SCK speed */
+ if ((PINC & (1 << PC2)) == 0) {
+ ispSetSCKOption(ISP_SCK_SLOW);
+ } else {
+ ispSetSCKOption(ISP_SCK_FAST);
+ }
+
+ ispConnect();
+ ledRedOn();
+
+ } else if (data[1] == USBASP_FUNC_DISCONNECT) {
+ ispDisconnect();
+ ledRedOff();
+
+ } else if (data[1] == USBASP_FUNC_TRANSMIT) {
+ replyBuffer[0] = ispTransmit(data[2]);
+ replyBuffer[1] = ispTransmit(data[3]);
+ replyBuffer[2] = ispTransmit(data[4]);
+ replyBuffer[3] = ispTransmit(data[5]);
+ len = 4;
+
+ } else if (data[1] == USBASP_FUNC_READFLASH) {
+ prog_address = (data[3] << 8) | data[2];
+ prog_nbytes = (data[7] << 8) | data[6];
+ prog_state = PROG_STATE_READFLASH;
+ len = 0xff; /* multiple in */
+
+ } else if (data[1] == USBASP_FUNC_READEEPROM) {
+ prog_address = (data[3] << 8) | data[2];
+ prog_nbytes = (data[7] << 8) | data[6];
+ prog_state = PROG_STATE_READEEPROM;
+ len = 0xff; /* multiple in */
+
+ } else if (data[1] == USBASP_FUNC_ENABLEPROG) {
+ replyBuffer[0] = ispEnterProgrammingMode();;
+ len = 1;
+
+ } else if (data[1] == USBASP_FUNC_WRITEFLASH) {
+ prog_address = (data[3] << 8) | data[2];
+ prog_pagesize = data[4];
+ prog_blockflags = data[5];
+ if (prog_blockflags & PROG_BLOCKFLAG_FIRST) {
+ prog_pagecounter = prog_pagesize;
+ }
+ prog_nbytes = (data[7] << 8) | data[6];
+ prog_state = PROG_STATE_WRITEFLASH;
+ len = 0xff; /* multiple out */
+
+ } else if (data[1] == USBASP_FUNC_WRITEEEPROM) {
+ prog_address = (data[3] << 8) | data[2];
+ prog_pagesize = 0;
+ prog_blockflags = 0;
+ prog_nbytes = (data[7] << 8) | data[6];
+ prog_state = PROG_STATE_WRITEEEPROM;
+ len = 0xff; /* multiple out */
+ }
+
+ usbMsgPtr = replyBuffer;
+
+ return len;
+}
+
+
+uchar usbFunctionRead(uchar *data, uchar len) {
+
+ uchar i;
+
+ /* check if programmer is in correct read state */
+ if ((prog_state != PROG_STATE_READFLASH) &&
+ (prog_state != PROG_STATE_READEEPROM)) {
+ return 0xff;
+ }
+
+ /* fill packet */
+ for (i = 0; i < len; i++) {
+ if (prog_state == PROG_STATE_READFLASH) {
+ data[i] = ispReadFlash(prog_address);
+ } else {
+ data[i] = ispReadEEPROM(prog_address);
+ }
+ prog_address++;
+ }
+
+ /* last packet? */
+ if (len < 8) {
+ prog_state = PROG_STATE_IDLE;
+ }
+
+ return len;
+}
+
+
+uchar usbFunctionWrite(uchar *data, uchar len) {
+
+ uchar i;
+
+ /* check if programmer is in correct write state */
+ if ((prog_state != PROG_STATE_WRITEFLASH) &&
+ (prog_state != PROG_STATE_WRITEEEPROM)) {
+ return 0xff;
+ }
+
+
+ for (i = 0; i < len; i++) {
+
+ if (prog_state == PROG_STATE_WRITEFLASH) {
+ /* Flash */
+
+ if (prog_pagesize == 0) {
+ /* not paged */
+ ispWriteFlash(prog_address, data[i], 1);
+ } else {
+ /* paged */
+ ispWriteFlash(prog_address, data[i], 0);
+ prog_pagecounter --;
+ if (prog_pagecounter == 0) {
+ ispFlushPage(prog_address, data[i]);
+ prog_pagecounter = prog_pagesize;
+ }
+ }
+
+ } else {
+ /* EEPROM */
+ ispWriteEEPROM(prog_address, data[i]);
+ }
+
+ prog_nbytes --;
+
+ if (prog_nbytes == 0) {
+ prog_state = PROG_STATE_IDLE;
+ if ((prog_blockflags & PROG_BLOCKFLAG_LAST) &&
+ (prog_pagecounter != prog_pagesize)) {
+
+ /* last block and page flush pending, so flush it now */
+ ispFlushPage(prog_address, data[i]);
+ }
+ }
+
+ prog_address ++;
+ }
+
+ return 0;
+}
+
+
+int main(void)
+{
+ PORTD = 0;
+ PORTB = 0; /* no pullups on USB and ISP pins */
+ DDRD = ~(1 << 2); /* all outputs except PD2 = INT0 */
+ DDRB = 0; /* all USB and ISP pins inputs */
+
+ DDRC = 0x03; /* all inputs except PC0, PC1 */
+ PORTC = 0xfe;
+
+ clockInit(); /* init timer */
+
+ ispSetSCKOption(ISP_SCK_FAST);
+
+ usbInit();
+ sei();
+ for(;;){ /* main event loop */
+ usbPoll();
+ }
+ return 0;
+}
--- /dev/null
+/* Name: usbconfig.h
+ * Project: AVR USB driver
+ * Author: Christian Starkjohann
+ * Creation Date: 2005-04-01
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: Proprietary, free under certain conditions. See Documentation.
+ * This Revision: $Id: usbconfig.h 43 2005-04-10 21:04:36Z cs $
+ */
+
+#ifndef __usbconfig_h_included__
+#define __usbconfig_h_included__
+
+/*
+General Description:
+This file contains parts of the USB driver which can be configured and can or
+must be adapted to your hardware.
+*/
+
+/* ---------------------------- Hardware Config ---------------------------- */
+
+#define USB_CFG_IOPORT PORTB
+/* This is the port where the USB bus is connected. When you configure it to
+ * "PORTB", the registers PORTB, PINB (=PORTB+2) and DDRB (=PORTB+1) will be
+ * used.
+ */
+#define USB_CFG_DMINUS_BIT 0
+/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
+ * This MUST be bit 0. All other values will result in a compile error!
+ */
+#define USB_CFG_DPLUS_BIT 1
+/* 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 also be connected
+ * to interrupt pin INT0!
+ */
+
+/* --------------------------- Functional Range ---------------------------- */
+
+#define USB_CFG_HAVE_INTRIN_ENDPOINT 0
+/* Define this to 1 if you want to compile a version with two endpoints: The
+ * default control endpoint 0 and an interrupt-in endpoint 1.
+ */
+#define USB_CFG_INTR_POLL_INTERVAL 10
+/* 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
+ * low speed devices.
+ */
+#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
+ * device is powered from the USB bus.
+ */
+#define USB_CFG_MAX_BUS_POWER 50
+/* Set this variable to the maximum USB bus power consumption of your device.
+ * The value is in milliamperes. [It will be divided by two since USB
+ * communicates power requirements in units of 2 mA.]
+ */
+#define USB_CFG_SAMPLE_EXACT 0
+/* This variable affects Sampling Jitter for USB receiving. When it is 0, the
+ * driver guarantees a sampling window of 1/2 bit. The USB spec requires
+ * that the receiver has at most 1/4 bit sampling window. The 1/2 bit window
+ * should still work reliably enough because we work at low speed. If you want
+ * to meet the spec, set this value to 1. This will unroll a loop which
+ * results in bigger code size.
+ * If you have problems with long cables, try setting this value to 1.
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITE 1
+/* 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 couple of
+ * bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_READ 1
+/* 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 send
+ * data from a static buffer, set it to 0 and return the data from
+ * usbFunctionSetup(). This saves a couple of bytes.
+ */
+
+/* -------------------------- Device Description --------------------------- */
+
+#define USB_CFG_VENDOR_ID 0xeb, 0x03
+/* USB vendor ID for the device, low byte first. 0xeb, 0x03 is Atmel's vendor
+ * ID. Don't use it for hardware you sell or publish!
+ */
+#define USB_CFG_DEVICE_ID 0xb4, 0xc7
+/* This is the ID of the device, low byte first. It is interpreted in the
+ * scope of the vendor ID. The only requirement is that no two devices may
+ * share the same product and vendor IDs. Not even if the devices are never
+ * on the same bus together!
+ */
+#define USB_CFG_DEVICE_VERSION 0x00, 0x01
+/* Version number of the device: Minor number first, then major number.
+ */
+#define USB_CFG_VENDOR_NAME 'w', 'w', 'w', '.', 'f', 'i', 's', 'c', 'h', 'l', '.', 'a', 't'
+#define USB_CFG_VENDOR_NAME_LEN 13
+/* 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. The characters
+ * are interpreted as Unicode (UTF-16) entities.
+ * If you don't want a vendor name string, undefine these macros.
+ */
+#define USB_CFG_DEVICE_NAME 'U', 'S', 'B', 'a', 's', 'p'
+#define USB_CFG_DEVICE_NAME_LEN 6
+/* Same as above for the device name. If you don't want a device name, undefine
+ * the macros.
+ */
+#define USB_CFG_DEVICE_CLASS 0xff
+#define USB_CFG_DEVICE_SUBCLASS 0
+/* See USB specification if you want to conform to an existing device class.
+ */
+#define USB_CFG_INTERFACE_CLASS 0
+#define USB_CFG_INTERFACE_SUBCLASS 0
+#define USB_CFG_INTERFACE_PROTOCOL 0
+/* See USB specification if you want to conform to an existing device class or
+ * protocol.
+ */
+
+
+#endif /* __usbconfig_h_included__ */
--- /dev/null
+This file documents changes in the software, firmware and hardware of the
+"Remote Sensor" device. New entries are always appended to the end of the file.
+Scroll down to the bottom to see the most recent changes.
+
+2005-04-01:
+ - Implemented endpoint 1 as interrupt-in endpoint.
+ - Moved all configuration options to usbconfig.h which is not part of the
+ driver.
+ - Changed interface for usbVendorSetup().
+ - Fixed compatibility with ATMega8 device.
+ - Various minor optimizations.
+
+2005-04-11:
+ - Changed interface to application: Use usbFunctionSetup(), usbFunctionRead()
+ and usbFunctionWrite() now. Added configuration options to choose which
+ of these functions to compile in.
+ - Assembler module delivers receive data non-inverted now.
+ - Made register and bit names compatible with more AVR devices.
--- /dev/null
+PREFACE
+
+Conceiving and understanding a new license is not an easy task. To make things
+easier for both, the author and the licensee, we have decided to base our
+license for the USB driver on an existing license with well-understood
+properties.
+
+Our favorite choice for the base license was the GNU General Public License
+(GPL). However, we cannot use the GNU GPL directly for the following reasons:
+
+(1) It was not intended for projects involving hardware -- we must extend the
+ term "source code" to at least the circuit diagram.
+(2) The GNU GPL does not require publication. Only if a binary is published,
+ it requires that the source is published as well. This is reasonable for
+ software because unpublished software is of little relevance. For projects
+ involving hardware, we want to REQUIRE publication. More than that, we
+ even want to define HOW the publication must be done (files contained,
+ file formats etc).
+(3) As the author of the software, we can distribute it under more than one
+ license. For people who don't want to meet the obligations of the GNU GPL,
+ we want to offer pay-by-unit business licenses. To avoid a split in
+ revisions of the driver, we need special privileges to distribute
+ contributed modifications under other licenses.
+
+We can not simply modify the GNU GPL and incorporate our changes because the
+Free Software Foundation (FSF) who holds the copyright for the text of the
+GNU GPL does not allow modifications. We therefore set up our own small
+license which incorporates the GNU GPL by reference:
+
+
+
+LICENSE FOR PROJECTS BUILT WITH "OBJECTIVE DEVELOPMENT'S
+FIRMWARE-ONLY USB-DRIVER FOR ATMEL'S AVR MICROCONTROLLERS"
+Version 2005-02
+
+
+I. Definitions
+
+"OBDEV" shall mean OBJECTIVE DEVELOPMENT Software GmbH or any legal successor
+thereof.
+
+"Software Source Code" shall mean the preferred form of the software for
+making modifications to it.
+
+"USB Driver" shall mean the Software Source Code for OBDEV's firmware-only
+USB-driver for Atmel's AVR microcontrollers.
+
+"Function" shall mean the Software Source Code for all software executed on
+the microcontroller except the USB Driver.
+
+"Host Software" shall mean the Software Source Code for all software required
+to control the USB device from the USB host running any operating system.
+
+"Project" shall mean the USB Driver, the Function, the Host Software, circuit
+diagrams of the controller based hardware and accompanying documentation.
+
+"source code" shall have the same meaning as the term "Project" above.
+
+"Web Site" shall mean a collection of text and multimedia documents accessible
+worldwide over internet through the HyperText Transfer Protocol (HTTP) on
+TCP port 80 (standard HTTP port).
+
+
+II. General License Terms
+The general terms of this license consist of the GNU General Public License
+Version 2 (GNU GPL2) which is hereby incorporated into this section as though
+it were fully set forth here. A copy of the GNU GPL2 is included for your
+convenience in appendix A of this license.
+
+The term "source code" in the GNU GPL2 is to be understood as defined in
+section I above. If any term or definition in section I, III, IV or V
+conflicts with the GNU GPL2, the term or definition in section I, III, IV or
+V has precedence of the GNU GPL2.
+
+
+III. Distribution of the Project
+The distributed form of a Project must contain at least the following files:
+(a) Software Source Code files for the USB Driver, the Function and the Host
+ Software.
+(b) Circuit diagrams for the hardware in PDF, PNG or GIF image file format.
+(c) A file with name "Readme.txt" in ASCII format with at least the following
+ content (in English language):
+ - An explanation what the Project does.
+ - What to do with the distributed files (installation procedure etc.).
+ - A reference to Objective Development's USB driver.
+ - Your (author's) name and contact information. E-mail and/or URL is
+ sufficient.
+(d) Optionally a text file with a description of the circuit diagram, an
+ explanation of special (software) techniques used etc.
+(e) A copy of this license in a file with the name "License.txt".
+
+
+IV. Requirement for Publication
+All modifications and derived work (Projects using the USB Driver) MUST be
+distributed (published) as described in section III above on a Web Site. The
+main page must reproduce at least a description of the Project (e.g. as
+contained in the "Readme.txt" file distributed) and a download link for the
+entire Project. The URL of the main page must be submitted to OBDEV. OBDEV
+will provide a mechanism for submitting Project URLs and for publishing
+Projects on their Web Site. The Project must remain available for at least
+twelve (12) months after the initial publication or at least six (6) months
+after a subsequent version of that particular Project has been published.
+
+
+V. Author Privileges
+OBDEV reserves the right to distribute the USB Driver and all modified
+versions under other (proprietary) licenses. If you modify the USB Driver
+under the grants of this license, you therefore grant OBDEV (in addition to
+the grants of the GNU GPL2) a worldwide, perpetual, irrevocable royalty free
+license for your modifications. OBDEV shall not automatically gain rights
+other than those of the GNU GPL2 in the other parts of the Project. This
+section V overrides possibly contradicting terms in the GNU GPL2 referenced
+in section II.
+
+
+APPENDIX A
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+/* Name: oddebug.c
+ * Project: AVR library
+ * Author: Christian Starkjohann
+ * Creation Date: 2005-01-16
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: Proprietary, free under certain conditions. See Documentation.
+ * This Revision: $Id: oddebug.c 52 2005-04-12 16:57:29Z cs $
+ */
+
+#include <avr/io.h>
+#include "oddebug.h"
+
+#if DEBUG_LEVEL > 0
+
+static void uartPutc(char c)
+{
+ while(!(ODDBG_USR & (1 << UDRE))); /* wait for data register empty */
+ ODDBG_UDR = c;
+}
+
+static uchar hexAscii(uchar h)
+{
+ h &= 0xf;
+ if(h < 10){
+ h += '0';
+ }else{
+ h += 'a' - (uchar)10;
+ }
+ return h;
+}
+
+static void printHex(uchar c)
+{
+ uartPutc(hexAscii(c >> 4));
+ uartPutc(hexAscii(c));
+}
+
+void odDebug(uchar prefix, uchar *data, uchar len)
+{
+ printHex(prefix);
+ uartPutc(':');
+ while(len--){
+ uartPutc(' ');
+ printHex(*data++);
+ }
+ uartPutc('\r');
+ uartPutc('\n');
+}
+
+#endif
--- /dev/null
+/* Name: oddebug.h
+ * Project: AVR library
+ * Author: Christian Starkjohann
+ * Creation Date: 2005-01-16
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: Proprietary, free under certain conditions. See Documentation.
+ * This Revision: $Id: oddebug.h 52 2005-04-12 16:57:29Z cs $
+ */
+
+#ifndef __oddebug_h_included__
+#define __oddebug_h_included__
+
+#include <avr/io.h>
+
+/*
+General Description:
+This module implements a function for debug logs on the serial line of the
+AVR microcontroller. Debugging can be configured with the define
+'DEBUG_LEVEL'. If this macro is not defined or defined to 0, all debugging
+calls are no-ops. If it is 1, DBG1 logs will appear, but not DBG2. If it is
+2, DBG1 and DBG2 logs will be printed.
+
+A debug log consists of a label ('prefix') to indicate which debug log created
+the output and a memory block to dump in hex ('data' and 'len').
+*/
+
+
+#ifndef F_CPU
+# define F_CPU 12000000 /* 12 MHz */
+#endif
+
+#ifndef uchar
+# define uchar unsigned char
+#endif
+
+#if DEBUG_LEVEL > 0 && !defined TXEN /* no UART in device */
+# warning "Debugging disabled because device has no UART"
+# undef DEBUG_LEVEL
+#endif
+
+#ifndef DEBUG_LEVEL
+# define DEBUG_LEVEL 0
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+#if DEBUG_LEVEL > 0
+# define DBG1(prefix, data, len) odDebug(prefix, data, len)
+#else
+# define DBG1(prefix, data, len)
+#endif
+
+#if DEBUG_LEVEL > 1
+# define DBG2(prefix, data, len) odDebug(prefix, data, len)
+#else
+# define DBG2(prefix, data, len)
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+#if DEBUG_LEVEL > 0
+extern void odDebug(uchar prefix, uchar *data, uchar len);
+
+/* Try to find our control registers; ATMEL likes to rename these */
+
+#if defined UBRR
+# define ODDBG_UBRR UBRR
+#elif defined UBRRL
+# define ODDBG_UBRR UBRRL
+#elif defined UBRR1
+# define ODDBG_UBRR UBRR1
+#elif defined UBRR1L
+# define ODDBG_UBRR UBRR1L
+#endif
+
+#if defined UCR
+# define ODDBG_UCR UCR
+#elif defined UCSRB
+# define ODDBG_UCR UCSRB
+#elif defined UCSR1B
+# define ODDBG_UCR UCSR1B
+#endif
+
+#if defined USR
+# define ODDBG_USR USR
+#elif defined UCSRA
+# define ODDBG_USR UCSRA
+#elif defined UCSR1A
+# define ODDBG_USR UCSR1A
+#endif
+
+#if defined UDR
+# define ODDBG_UDR UDR
+#elif defined UDR1
+# define ODDBG_UDR UDR1
+#endif
+
+static inline void odDebugInit(void)
+{
+ ODDBG_UCR |= (1<<TXEN);
+ ODDBG_UBRR = F_CPU / (19200 * 16L) - 1;
+}
+#else
+# define odDebugInit()
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+#endif /* __oddebug_h_included__ */
--- /dev/null
+/* Name: usbdrv.c
+ * Project: AVR USB driver
+ * Author: Christian Starkjohann
+ * Creation Date: 2004-12-29
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: Proprietary, free under certain conditions. See Documentation.
+ * This Revision: $Id: usbdrv.c 53 2005-04-12 17:11:29Z cs $
+ */
+
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include "usbdrv.h"
+#include "oddebug.h"
+
+/*
+General Description:
+This module implements the C-part of the USB driver. See usbdrv.h for a
+documentation of the entire driver.
+*/
+
+/* ------------------------------------------------------------------------- */
+
+/* raw USB registers / interface to assembler code: */
+/* usbRxBuf MUST be in 1 byte addressable range (because usbInputBuf is only 1 byte) */
+static char usbRxBuf[2][USB_BUFSIZE];/* raw RX buffer: PID, 8 bytes data, 2 bytes CRC */
+uchar usbDeviceId; /* assigned during enumeration, defaults to 0 */
+uchar usbInputBuf; /* ptr to raw buffer used for receiving */
+uchar usbAppBuf; /* ptr to raw buffer passed to app for processing */
+volatile char usbRxLen; /* = 0; number of bytes in usbAppBuf; 0 means free */
+uchar usbCurrentTok; /* last token received */
+uchar usbRxToken; /* token for data we received */
+uchar usbMsgLen = 0xff; /* remaining number of bytes, no msg to send if -1 (see usbMsgPtr) */
+volatile char usbTxLen = -1; /* number of bytes to transmit with next IN token */
+uchar usbTxBuf[USB_BUFSIZE];/* data to transmit with next IN, free if usbTxLen == -1 */
+#if USB_CFG_HAVE_INTRIN_ENDPOINT
+/* uchar usbRxEndp; endpoint which was addressed (1 bit in MSB) [not impl] */
+volatile char usbTxLen1 = -1; /* TX count for endpoint 1 */
+uchar usbTxBuf1[USB_BUFSIZE];/* TX data for endpoint 1 */
+#endif
+uchar usbAckBuf[1] = {USBPID_ACK}; /* transmit buffer for ack tokens */
+uchar usbNakBuf[1] = {USBPID_NAK}; /* transmit buffer for nak tokens */
+
+/* USB status registers / not shared with asm code */
+uchar *usbMsgPtr; /* data to transmit next -- ROM or RAM address */
+static uchar usbMsgFlags; /* flag values see below */
+static uchar usbNewDeviceId; /* = 0; device ID which should be set after status phase */
+static uchar usbIsReset; /* = 0; USB bus is in reset phase */
+
+#define USB_FLG_TX_PACKET (1<<0)
+/* Leave free 6 bits after TX_PACKET. This way we can increment usbMsgFlags to toggle TX_PACKET */
+#define USB_FLG_MSGPTR_IS_ROM (1<<6)
+#define USB_FLG_USE_DEFAULT_RW (1<<7)
+
+/*
+optimizing hints:
+- do not post/pre inc/dec integer values in operations
+- 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
+- assign char sized expressions to variables to force 8 bit arithmetics
+*/
+
+/* ------------------------------------------------------------------------- */
+
+static char usbDescrDevice[] PROGMEM = { /* USB device descriptor */
+ 18, /* sizeof(usbDescrDevice): length of descriptor in bytes */
+ 1, /* descriptor type */
+ 0x01, 0x01, /* USB version supported */
+ USB_CFG_DEVICE_CLASS,
+ USB_CFG_DEVICE_SUBCLASS,
+ 0, /* protocol */
+ 8, /* max packet size */
+ USB_CFG_VENDOR_ID, /* 2 bytes */
+ USB_CFG_DEVICE_ID, /* 2 bytes */
+ USB_CFG_DEVICE_VERSION, /* 2 bytes */
+#if USB_CFG_VENDOR_NAME_LEN
+ 1, /* manufacturer string index */
+#else
+ 0, /* manufacturer string index */
+#endif
+#if USB_CFG_DEVICE_NAME_LEN
+ 2, /* product string index */
+#else
+ 0, /* product string index */
+#endif
+ 0, /* serial number string index */
+ 1, /* number of configurations */
+};
+
+static char usbDescrConfig[] PROGMEM = { /* USB configuration descriptor */
+ 9, /* sizeof(usbDescrConfig): length of descriptor in bytes */
+ 2, /* descriptor type */
+ (18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT), 0, /* total length of data returned (including inlined descriptors) */
+ 1, /* number of interfaces in this configuration */
+ 1, /* index of this configuration */
+ 0, /* configuration name string index */
+#if USB_CFG_IS_SELF_POWERED
+ USBATTR_SELFPOWER, /* attributes */
+#else
+ USBATTR_BUSPOWER, /* attributes */
+#endif
+ USB_CFG_MAX_BUS_POWER/2, /* max USB current in 2mA units */
+/* interface descriptor follows inline: */
+ 9, /* sizeof(usbDescrInterface): length of descriptor in bytes */
+ 4, /* descriptor type */
+ 0, /* index of this interface */
+ 0, /* alternate setting for this interface */
+ USB_CFG_HAVE_INTRIN_ENDPOINT, /* endpoints excl 0: number of endpoint descriptors to follow */
+ USB_CFG_INTERFACE_CLASS,
+ USB_CFG_INTERFACE_SUBCLASS,
+ USB_CFG_INTERFACE_PROTOCOL,
+ 0, /* string index for interface */
+#if USB_CFG_HAVE_INTRIN_ENDPOINT /* endpoint descriptor for endpoint 1 */
+ 7, /* sizeof(usbDescrEndpoint) */
+ 5, /* descriptor type = endpoint */
+ 0x81, /* IN endpoint number 1 */
+ 0x03, /* attrib: Interrupt endpoint */
+ 8, 0, /* maximum packet size */
+ USB_CFG_INTR_POLL_INTERVAL, /* in ms */
+#endif
+};
+
+static char usbDescrString0[] PROGMEM = { /* language descriptor */
+ 4, /* sizeof(usbDescrString0): length of descriptor in bytes */
+ 3, /* descriptor type */
+ 0x09, 0x04, /* language index (0x0409 = US-English) */
+};
+
+#if USB_CFG_VENDOR_NAME_LEN
+static int usbDescrString1[] PROGMEM = {
+ (2 * USB_CFG_VENDOR_NAME_LEN + 2) | (3<<8), /* length of descriptor in bytes | descriptor type */
+ USB_CFG_VENDOR_NAME
+};
+#endif
+#if USB_CFG_DEVICE_NAME_LEN
+static int usbDescrString2[] PROGMEM = {
+ (2 * USB_CFG_DEVICE_NAME_LEN + 2) | (3<<8), /* length of descriptor in bytes | descriptor type */
+ USB_CFG_DEVICE_NAME
+};
+#endif
+
+/* 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
+
+typedef union{
+ unsigned word;
+ uchar *ptr;
+ uchar bytes[2];
+}converter_t;
+/* We use this union to do type conversions. This is better optimized than
+ * type casts in gcc 3.4.3 and much better than using bit shifts to build
+ * ints from chars. Byte ordering is not a problem on an 8 bit platform.
+ */
+
+/* ------------------------------------------------------------------------- */
+
+#if USB_CFG_HAVE_INTRIN_ENDPOINT
+static uchar usbTxPacketCnt1;
+
+void usbSetInterrupt(uchar *data, uchar len)
+{
+uchar *p, i;
+converter_t crc;
+
+ if(len > 7)
+ len = 7;
+ i = USBPID_DATA1;
+ if(usbTxPacketCnt1 & 1)
+ i = USBPID_DATA0;
+ if(usbTxLen1 < 0){ /* packet buffer was empty */
+ usbTxPacketCnt1++;
+ }else{
+ usbTxLen1 = -1; /* avoid sending incomplete interrupt data */
+ }
+ p = usbTxBuf1;
+ *p++ = i;
+ for(i=len;i--;)
+ *p++ = *data++;
+ crc.word = usbCrc16(&usbTxBuf1[1], len);
+ usbTxBuf1[len + 1] = crc.bytes[0];
+ usbTxBuf1[len + 2] = crc.bytes[1];
+ usbTxLen1 = len + 4; /* len must be given including sync byte */
+}
+#endif
+
+static void usbWrite(uchar *data, uchar len)
+{
+#if USB_CFG_IMPLEMENT_FN_WRITE
+ if(!(usbMsgFlags & USB_FLG_USE_DEFAULT_RW)){
+ if(usbFunctionWrite(data, len) == 0xff){ /* an error occurred */
+ /* usbMsgLen = 0xff; cancel potentially pending ACK [has been done by ASM module when OUT token arrived] */
+ usbTxBuf[0] = USBPID_STALL;
+ usbTxLen = 2; /* length including sync byte */
+ return;
+ }
+ }
+#endif
+ usbMsgLen = 0; /* send zero-sized block as ACK */
+ usbMsgFlags = 0; /* start with a DATA1 package */
+}
+
+static uchar usbRead(uchar *data, uchar len)
+{
+#if USB_CFG_IMPLEMENT_FN_READ
+ if(usbMsgFlags & USB_FLG_USE_DEFAULT_RW){
+#endif
+ uchar i = len, *r = usbMsgPtr;
+ if(usbMsgFlags & USB_FLG_MSGPTR_IS_ROM){ /* ROM data */
+ while(i--){
+ char c = PRG_RDB(r); /* assign to char size variable to enforce byte ops */
+ *data++ = c;
+ r++;
+ }
+ }else{ /* RAM data */
+ while(i--)
+ *data++ = *r++;
+ }
+ usbMsgPtr = r;
+ return len;
+#if USB_CFG_IMPLEMENT_FN_READ
+ }else{
+ if(len != 0) /* don't bother app with 0 sized reads */
+ return usbFunctionRead(data, len);
+ return 0;
+ }
+#endif
+}
+
+/* Don't make this function static to avoid inlining.
+ * The entire function would become too large and exceed the range of
+ * relative jumps.
+ */
+void usbProcessRx(uchar *data, uchar len)
+{
+/* We use if() cascades because the compare is done byte-wise while switch()
+ * is int-based. The if() cascades are therefore more efficient.
+ */
+ DBG2(0x10 + (usbRxToken == (uchar)USBPID_SETUP), data, len);
+ if(usbRxToken == (uchar)USBPID_SETUP){
+ uchar replyLen = 0, flags = USB_FLG_USE_DEFAULT_RW;
+ if(len == 8){ /* Setup size must be always 8 bytes. Ignore otherwise. */
+ uchar type = data[0] & (3 << 5);
+ if(type == USBRQ_TYPE_STANDARD << 5){
+ uchar *replyData = usbTxBuf + 9; /* there is 3 bytes free space at the end of the buffer */
+ replyData[0] = 0;
+ if(data[1] == 0){/* GET_STATUS */
+#if USB_CFG_IS_SELF_POWERED
+ uchar recipient = data[0] & 0x1f; /* assign arith ops to variables to enforce byte size */
+ if(recipient == USBRQ_RCPT_DEVICE)
+ replyData[0] = USB_CFG_IS_SELF_POWERED;
+#endif
+ replyData[1] = 0;
+ replyLen = 2;
+ }else if(data[1] == 5){ /* SET_ADDRESS */
+ usbNewDeviceId = data[2];
+ }else if(data[1] == 6){ /* GET_DESCRIPTOR */
+ flags = USB_FLG_MSGPTR_IS_ROM | USB_FLG_USE_DEFAULT_RW;
+ if(data[3] == 1){ /* descriptor type requested */
+ replyLen = sizeof(usbDescrDevice);
+ replyData = (uchar *)usbDescrDevice;
+ }else if(data[3] == 2){
+ replyLen = sizeof(usbDescrConfig);
+ replyData = (uchar *)usbDescrConfig;
+ }else if(data[3] == 3){ /* string descriptor */
+ if(data[2] == 0){ /* descriptor index */
+ replyLen = sizeof(usbDescrString0);
+ replyData = (uchar *)usbDescrString0;
+#if USB_CFG_VENDOR_NAME_LEN
+ }else if(data[2] == 1){
+ replyLen = sizeof(usbDescrString1);
+ replyData = (uchar *)usbDescrString1;
+#endif
+#if USB_CFG_DEVICE_NAME_LEN
+ }else if(data[2] == 2){
+ replyLen = sizeof(usbDescrString2);
+ replyData = (uchar *)usbDescrString2;
+#endif
+ }
+ }
+ }else if(data[1] == 8){ /* GET_CONFIGURATION */
+ replyLen = 1;
+ replyData[0] = 1; /* config is always 1, no setConfig required */
+ }else if(data[1] == 10){ /* GET_INTERFACE */
+ replyLen = 1;
+#if USB_CFG_HAVE_INTRIN_ENDPOINT
+ }else if(data[1] == 11){ /* SET_INTERFACE */
+ usbTxPacketCnt1 = 0; /* reset data toggling for interrupt socket */
+#endif
+ }else{
+ /* the following requests can be ignored, send default reply */
+ /* 1: CLEAR_FEATURE, 3: SET_FEATURE, 7: SET_DESCRIPTOR */
+ /* 9: SET_CONFIGURATION, 11: SET_INTERFACE, 12: SYNCH_FRAME */
+ }
+ usbMsgPtr = replyData;
+ if(!data[7] && replyLen > data[6]) /* max length is in data[7]:data[6] */
+ replyLen = data[6];
+ }else{ /* not a standard request -- must be vendor or class request */
+#if USB_CFG_IMPLEMENT_FN_READ || USB_CFG_IMPLEMENT_FN_WRITE
+ uchar len;
+ replyLen = data[6]; /* if this is an OUT operation, the next token will reset usbMsgLen */
+ if((len = usbFunctionSetup(data)) != 0xff){
+ replyLen = len;
+ }else{
+ flags = 0; /* we have no valid msg, use read/write functions */
+ }
+#else
+ replyLen = usbFunctionSetup(data);
+#endif
+ }
+ }
+ usbMsgLen = replyLen;
+ usbMsgFlags = flags;
+ }else{ /* out request */
+ usbWrite(data, len);
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void usbBuildTxBlock(void)
+{
+uchar wantLen, len, txLen, x;
+converter_t crc;
+
+ x = USBPID_DATA1;
+ if(usbMsgFlags & USB_FLG_TX_PACKET)
+ x = USBPID_DATA0;
+ usbMsgFlags++;
+ usbTxBuf[0] = x;
+ wantLen = usbMsgLen;
+ if(wantLen > 8)
+ wantLen = 8;
+ usbMsgLen -= wantLen;
+ len = usbRead(usbTxBuf + 1, wantLen);
+ if(len <= 8){ /* valid data packet */
+ crc.word = usbCrc16(&usbTxBuf[1], len);
+ usbTxBuf[len + 1] = crc.bytes[0];
+ usbTxBuf[len + 2] = crc.bytes[1];
+ txLen = len + 4; /* length including sync byte */
+ if(len < 8) /* a partial package identifies end of message */
+ usbMsgLen = 0xff;
+ }else{
+ usbTxBuf[0] = USBPID_STALL;
+ txLen = 2; /* length including sync byte */
+ usbMsgLen = 0xff;
+ }
+ usbTxLen = txLen;
+ DBG2(0x20, usbTxBuf, txLen-1);
+}
+
+static inline uchar isNotSE0(void)
+{
+uchar rval;
+/* We want to do
+ * return (USBIN & USBMASK);
+ * here, but the compiler does int-expansion acrobatics.
+ * We can avoid this by assigning to a char-sized variable.
+ */
+ rval = USBIN & USBMASK;
+ return rval;
+}
+
+/* ------------------------------------------------------------------------- */
+
+void usbPoll(void)
+{
+uchar len;
+
+ if((len = usbRxLen) > 0){
+/* We could check CRC16 here -- but ACK has already been sent anyway. If you
+ * need data integrity checks with this driver, check the CRC in your app
+ * code and report errors back to the host. Since the ACK was already sent,
+ * retries must be handled on application level.
+ * unsigned crc = usbCrc16((uchar *)(unsigned)(usbAppBuf + 1), usbRxLen - 3);
+ */
+ len -= 3; /* remove PID and CRC */
+ if(len < 128){
+ usbProcessRx((uchar *)(unsigned)(usbAppBuf + 1), len);
+ }
+ usbRxLen = 0; /* mark rx buffer as available */
+ }
+ if(usbTxLen < 0){ /* TX system is idle */
+ if(usbMsgLen != 0xff){
+ usbBuildTxBlock();
+ }else if(usbNewDeviceId){
+ usbDeviceId = usbNewDeviceId;
+ DBG1(1, &usbNewDeviceId, 1);
+ usbNewDeviceId = 0;
+ }
+ }
+ if(isNotSE0()){ /* SE0 state */
+ usbIsReset = 0;
+ }else{
+ /* check whether SE0 lasts for more than 2.5us (3.75 bit times) */
+ if(!usbIsReset){
+ uchar i;
+ for(i=100;i;i--){
+ if(isNotSE0())
+ goto notUsbReset;
+ }
+ usbIsReset = 1;
+ usbDeviceId = 0;
+ usbNewDeviceId = 0;
+ DBG1(0xff, 0, 0);
+notUsbReset:;
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+void usbInit(void)
+{
+ usbInputBuf = (uchar)usbRxBuf[0];
+ usbAppBuf = (uchar)usbRxBuf[1];
+#if USB_INTR_CFG_SET != 0
+ USB_INTR_CFG |= USB_INTR_CFG_SET;
+#endif
+#if USB_INTR_CFG_CLR != 0
+ USB_INTR_CFG &= ~(USB_INTR_CFG_CLR);
+#endif
+ USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
+}
+
+/* ------------------------------------------------------------------------- */
--- /dev/null
+/* Name: usbdrv.h
+ * Project: AVR USB driver
+ * Author: Christian Starkjohann
+ * Creation Date: 2004-12-29
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: Proprietary, free under certain conditions. See Documentation.
+ * This Revision: $Id: usbdrv.h 52 2005-04-12 16:57:29Z cs $
+ */
+
+#ifndef __usbdrv_h_included__
+#define __usbdrv_h_included__
+#include "usbconfig.h"
+
+/*
+Hardware Prerequisites:
+=======================
+USB lines D+ and D- MUST be wired to the same I/O port. Line D- MUST be wired
+to bit number 0. D+ must also be connected to INT0. D- requires a pullup of
+1.5k to +3.5V (and the device must be powered at 3.5V) to identify as
+low-speed USB device. A pullup of 1M SHOULD be connected from D+ to +3.5V to
+prevent interference when no USB master is connected. We use D+ as interrupt
+source and not D- because it does not trigger on keep-alive and RESET states.
+
+Please adapt the values in usbconfig.h according to your hardware!
+
+The device MUST be clocked at 12 MHz. This is more than the 10 MHz allowed by
+an AT90S2313 powered at 4.5V. However, if the supply voltage to maximum clock
+relation is interpolated linearly, an ATtiny2313 meets the requirement by
+specification. In practice, the AT90S2313 can be overclocked and works well.
+
+
+Limitations:
+============
+Compiling:
+The bss segment of the driver must be in the first 256 bytes of the address
+space because byte wide variables are used as pointers for efficiency reasons.
+This is not a problem on devices with 128 byte RAM since the entire RAM
+meets this condition. For larger devices please link usbdrv first.
+
+Robustness with respect to communication errors:
+The driver assumes error-free communication. It DOES check for errors in
+the PID, but does NOT check bit stuffing errors, SE0 in middle of a byte,
+token CRC (5 bit) and data CRC (16 bit). CRC checks can not be performed due
+to timing constraints: We must start sending a reply within 7 bit times.
+Bit stuffing and misplaced SE0 would have to be checked in real-time, but CPU
+performance does not permit that. The driver does not check Data0/Data1
+toggling, but application software can implement the check.
+
+Sampling jitter:
+The driver guarantees a sampling window of 1/2 bit. The USB spec requires
+that the receiver has at most 1/4 bit sampling window. The 1/2 bit window
+should still work reliably enough because we work at low speed. If you want
+to meet the spec, define the macro "USB_CFG_SAMPLE_EXACT" to 1 in usbconfig.h.
+This will unroll a loop which results in bigger code size.
+
+Input characteristics:
+Since no differential receiver circuit is used, electrical interference
+robustness may suffer. The driver samples only one of the data lines with
+an ordinary I/O pin's input characteristics. However, since this is only a
+low speed USB implementation and the specification allows for 8 times the
+bit rate over the same hardware, we should be on the safe side. Even the spec
+requires detection of asymmetric states at high bit rate for SE0 detection.
+
+Number of endpoints:
+The driver supports up to two endpoints: One control endpoint (endpoint 0) and
+one interrupt-in endpoint (endpoint 1) where the device can send interrupt
+data to the host. Endpoint 1 is only compiled in if
+USB_CFG_HAVE_INTRIN_ENDPOINT is defined to 1 in usbconfig.h.
+
+Maximum data payload:
+Data payload of control in and out transfers may be up to 255 bytes. In order
+to accept payload data of out transfers, you need to implement
+'usbFunctionWrite()'.
+
+USB Suspend Mode supply current:
+The USB standard limits power consumption to 500uA when the bus is in suspend
+mode. This is not a problem for self-powered devices since they don't need
+bus power anyway. Bus-powered devices can achieve this only by putting the
+CPU in sleep mode. The driver does not implement suspend handling by itself.
+However, the application may implement activity monitoring and wakeup from
+sleep. The host sends regular SE0 states on the bus to keep it active. These
+SE0 states can be detected by wiring the INT1 pin to D+. It is not necessary
+to enable the interrupt, checking the interrupt pending flag should suffice.
+Before entering sleep mode, the application should enable INT1 for a wakeup
+on the next bus activity.
+
+Operation without an USB master:
+The driver behaves neutral without connection to an USB master if D- reads
+as 1. To avoid spurious interrupts, we recommend a high impedance (e.g. 1M)
+pullup resistor on D+. If D- becomes statically 0, the driver may block in
+the interrupt routine.
+
+Interrupt latency:
+The application must ensure that the USB interrupt is not disabled for more
+than 20 cycles.
+
+Maximum interrupt duration / CPU cycle consumption:
+The driver handles all USB communication during the interrupt service
+routine. The routine will not return before an entire USB message is received
+and the reply is sent. This may be up to ca. 1200 cycles = 100us if the host
+conforms to the standard. The driver will consume CPU cycles for all USB
+messages, even if they address an other (low-speed) device on the same bus.
+
+*/
+
+/* ------------------------------------------------------------------------- */
+/* --------------------------- Module Interface ---------------------------- */
+/* ------------------------------------------------------------------------- */
+
+#ifndef __ASSEMBLER__
+
+#ifndef uchar
+#define uchar unsigned char
+#endif
+
+#if USB_CFG_HAVE_INTRIN_ENDPOINT
+void usbSetInterrupt(uchar *data, uchar len);
+/* This function sets the message which will be sent during the next interrupt
+ * IN transfer. The message is copied to an internal buffer and must not exceed
+ * a length of 7 bytes. The message may be 0 bytes long just to indicate the
+ * interrupt status to the host.
+ * If you need to transfer more bytes, use a control read after the interrupt.
+ */
+#endif /* USB_CFG_HAVE_INTRIN_ENDPOINT */
+
+extern void usbInit(void);
+/* This function must be called before interrupts are enabled and the main
+ * loop is entered.
+ */
+extern void usbPoll(void);
+/* This function must be called at regular intervals from the main loop.
+ * Maximum delay between calls is somewhat less than 50ms (USB timeout between
+ * packages of a message).
+ */
+extern uchar *usbMsgPtr;
+/* This variable may be used to pass transmit data to the driver from the
+ * implementation of usbFunctionWrite(). It is also used internally by the
+ * driver for standard control requests.
+ */
+extern uchar usbFunctionSetup(uchar data[8]);
+/* This function is called for all setup requests which are not of type
+ * "Standard" (in practice: class and vendor requests). The 8 bytes setup
+ * data is passed in 'data'. Data for control-out transfers is passed to the
+ * application in separate calls to usbFunctionWrite() (unless you have turned
+ * this option off). You should store the setup context in global/static
+ * variables to have it available in usbFunctionWrite(). Data for control-in
+ * transfers can be provided in two ways: (1) immediately as a result of
+ * usbFunctionSetup() or (2) on demand of the driver in calls to the separate
+ * function usbFunctionRead() (if enabled). For (1) write the data to a static
+ * buffer, set the global variable 'usbMsgPtr' to this buffer and return the
+ * data length (may be 0). To implement (2), simply return 0xff (== -1) in
+ * usbFunctionSetup(). The driver will call usbFunctionRead() when data is
+ * needed. You may use 'usbMsgPtr' to save your own status in this case.
+ * The data passed in 'data' has the following content (see USB 1.1 spec):
+ * struct usbControlData{
+ * uchar requestType; //[0]
+ * uchar request; //[1]
+ * unsigned value; //[2], [3]
+ * unsigned index; //[4], [5]
+ * unsigned length; //[6], [7]
+ * };
+ */
+#if USB_CFG_IMPLEMENT_FN_WRITE
+extern uchar usbFunctionWrite(uchar *data, uchar len);
+/* This function is called by the driver to provide a control transfer's
+ * payload data (control-out). It is called in chunks of up to 8 bytes. The
+ * total count provided in the current control transfer can be obtained from
+ * the 'length' property in the setup data. If an error occurred during
+ * processing, return 0xff (== -1). The driver will answer the entire transfer
+ * with a STALL token in this case. Otherwise return any number which is not
+ * 0xff. NOTE: Only the return value of the LAST usbFunctionWrite() call
+ * (the one immediately before the status phase) is used.
+ */
+#endif /* USB_CFG_IMPLEMENT_FN_WRITE */
+#if USB_CFG_IMPLEMENT_FN_READ
+extern uchar usbFunctionRead(uchar *data, uchar len);
+/* This function is called by the driver to ask the application for a control
+ * transfer's payload data (control-in). You should supply up to 'len' bytes of
+ * data in this chunk. 'len' will be 8 bytes for all but the last chunk. If
+ * you return less than 8 bytes, the control transfer ends. If you return an
+ * invalid value (e.g. -1), the driver sends a STALL token.
+ */
+#endif /* USB_CFG_IMPLEMENT_FN_READ */
+extern unsigned usbCrc16(uchar *data, uchar len);
+/* This function calculates the binary complement of the data CRC used in
+ * USB data packets. The value is used to build raw transmit packets.
+ * You may want to use this function for data checksums.
+ */
+
+#endif /* __ASSEMBLER__ */
+
+/* ------------------------------------------------------------------------- */
+/* ------------------------- Constant definitions -------------------------- */
+/* ------------------------------------------------------------------------- */
+
+/* I/O definitions for assembler module */
+#define USBOUT USB_CFG_IOPORT /* output port for USB bits */
+#ifdef __ASSEMBLER__
+#define USBIN (USB_CFG_IOPORT - 2) /* input port for USB bits */
+#define USBDDR (USB_CFG_IOPORT - 1) /* data direction for USB bits */
+#else
+#define USBIN (*(&USB_CFG_IOPORT - 2)) /* input port for USB bits */
+#define USBDDR (*(&USB_CFG_IOPORT - 1)) /* data direction for USB bits */
+#endif
+#if USB_CFG_DMINUS_BIT != 0
+# error "USB_CFG_DMINUS_BIT MUST be 0!"
+#endif
+#define USBMINUS 0 /* D- MUST be on bit 0 */
+#define USBIDLE 0x01 /* value representing J state */
+#define USBMASK ((1<<USB_CFG_DPLUS_BIT) | 1) /* mask for USB I/O bits */
+
+#define USB_BUFSIZE 11 /* PID, 8 bytes data, 2 bytes CRC */
+
+/* Try to find registers and bits responsible for ext interrupt 0 */
+
+#if defined EICRA
+# define USB_INTR_CFG EICRA
+#else
+# define USB_INTR_CFG MCUCR
+#endif
+#define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) /* cfg for rising edge */
+#define USB_INTR_CFG_CLR 0 /* no bits to clear */
+
+#if defined GIMSK
+# define USB_INTR_ENABLE GIMSK
+#elif defined EIMSK
+# define USB_INTR_ENABLE EIMSK
+#else
+# define USB_INTR_ENABLE GICR
+#endif
+#define USB_INTR_ENABLE_BIT INT0
+
+#if defined EIFR
+# define USB_INTR_PENDING EIFR
+#else
+# define USB_INTR_PENDING GIFR
+#endif
+#define USB_INTR_PENDING_BIT INTF0
+
+/*
+The defines above don't work for the following chips
+at90c8534: no ISC0?, no PORTB, can't find a data sheet
+at86rf401: no PORTB, no MCUCR etc
+atmega103: no ISC0? (maybe omission in header, can't find data sheet)
+atmega603: not defined in avr-libc
+at43usb320, at43usb355, at76c711: have USB anyway
+at94k: is different...
+
+at90s1200, attiny11, attiny12, attiny15, attiny28: these have no RAM
+*/
+
+/* ------------------------------------------------------------------------- */
+/* ---------------------- USB Specification Constants ---------------------- */
+/* ------------------------------------------------------------------------- */
+
+/* USB Token values */
+#define USBPID_SETUP 0x2d
+#define USBPID_OUT 0xe1
+#define USBPID_IN 0x69
+#define USBPID_DATA0 0xc3
+#define USBPID_DATA1 0x4b
+
+#define USBPID_ACK 0xd2
+#define USBPID_NAK 0x5a
+#define USBPID_STALL 0x1e
+
+/* USB descriptor constants */
+#define USBATTR_BUSPOWER 0x80
+#define USBATTR_SELFPOWER 0x40
+#define USBATTR_REMOTEWAKE 0x20
+
+/* USB setup recipient values */
+#define USBRQ_RCPT_DEVICE 0
+#define USBRQ_RCPT_INTERFACE 1
+#define USBRQ_RCPT_ENDPOINT 2
+
+/* USB request type values */
+#define USBRQ_TYPE_STANDARD 0
+#define USBRQ_TYPE_CLASS 1
+#define USBRQ_TYPE_VENDOR 2
+
+
+/* ------------------------------------------------------------------------- */
+
+#endif /* __usbdrv_h_included__ */
--- /dev/null
+/* Name: usbdrvasm.S
+ * Project: AVR USB driver
+ * Author: Christian Starkjohann
+ * Creation Date: 2004-12-29
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: Proprietary, free under certain conditions. See Documentation.
+ * This Revision: $Id: usbdrvasm.S 52 2005-04-12 16:57:29Z cs $
+ */
+
+/*
+General Description:
+This module implements the assembler part of the USB driver. See usbdrv.h
+for a description of the entire driver.
+Since almost all of this code is timing critical, don't change unless you
+really know what you are doing! Many parts require not only a maximum number
+of CPU cycles, but even an exact number of cycles!
+*/
+
+/* 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 */
+#include "usbdrv.h" /* for common defs */
+
+
+/* register names */
+#define x1 r16
+#define x2 r17
+#define shift r18
+#define cnt r19
+#define x3 r20
+#define x4 r21
+
+#define nop2 rjmp .+0 /* jump to next instruction */
+
+.text
+
+.global SIG_INTERRUPT0
+ .type SIG_INTERRUPT0, @function
+SIG_INTERRUPT0:
+;Software-receiver engine. Strict timing! Don't change unless you can preserve timing!
+;interrupt response time: 4 cycles + insn running = 7 max if interrupts always enabled
+;max allowable interrupt latency: 32 cycles -> max 25 cycles interrupt disable
+;max stack usage: [ret(2), x1, SREG, x2, cnt, shift, YH, YL, x3, x4] = 11 bytes
+usbInterrupt:
+;order of registers pushed:
+;x1, SREG, x2, cnt, shift, [YH, YL, x3]
+ push x1 ;2 push only what is necessary to sync with edge ASAP
+ in x1, SREG ;1
+ push x1 ;2
+;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
+;first part has no timeout because it waits for IDLE or SE1 (== disconnected)
+#if !USB_CFG_SAMPLE_EXACT
+ ldi x1, 5 ;1 setup a timeout for waitForK
+#endif
+waitForJ:
+ sbis USBIN, USBMINUS ;1 wait for D- == 1
+ rjmp waitForJ ;2
+#if USB_CFG_SAMPLE_EXACT
+;The following code represents the unrolled loop in the else branch. It
+;results in a sampling window of 1/4 bit which meets the spec.
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ nop
+ nop2
+foundK:
+#else
+waitForK:
+ dec x1 ;1
+ sbic USBIN, USBMINUS ;1 wait for D- == 0
+ brne waitForK ;2
+#endif
+;{2, 6} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling]
+;we have 1 bit time for setup purposes, then sample again:
+ push x2 ;2
+ push cnt ;2
+ push shift ;2
+shortcutEntry:
+ ldi cnt, 1 ;1 pre-init bit counter (-1 because no dec follows, -1 because 1 bit already sampled)
+ ldi x2, 1<<USB_CFG_DPLUS_BIT ;1 -> 8 edge sync ended with D- == 0
+;now wait until SYNC byte is over. Wait for either 2 bits low (success) or 2 bits high (failure)
+waitNoChange:
+ in x1, USBIN ;1 <-- sample, timing: edge + {2, 6} cycles
+ eor x2, x1 ;1
+ sbrc x2, 0 ;1 | 2
+ ldi cnt, 2 ;1 | 0 cnt = numBits - 1 (because dec follows)
+ mov x2, x1 ;1
+ dec cnt ;1
+ brne waitNoChange ;2 | 1
+ sbrc x1, USBMINUS ;2
+ rjmp sofError ;0 two consecutive "1" bits -> framing error
+;start reading data, but don't check for bitstuffing because these are the
+;first bits. Use the cycles for initialization instead. Note that we read and
+;store the binary complement of the data stream because eor results in 1 for
+;a change and 0 for no change.
+ in x1, USBIN ;1 <-- sample bit 0, timing: edge + {3, 7} cycles
+ eor x2, x1 ;1
+ ror x2 ;1
+ ldi shift, 0x7f ;1 The last bit of the sync pattern was a "no change"
+ ror shift ;1
+ push YH ;2 -> 7
+ in x2, USBIN ;1 <-- sample bit 1, timing: edge + {2, 6} cycles
+ eor x1, x2 ;1
+ ror x1 ;1
+ ror shift ;1
+ push YL ;2
+ lds YL, usbInputBuf ;2 -> 8
+ in x1, USBIN ;1 <-- sample bit 2, timing: edge + {2, 6} cycles
+ eor x2, x1 ;1
+ ror x2 ;1
+ ror shift ;1
+ ldi cnt, USB_BUFSIZE;1
+ clr YH ;1
+ push x3 ;2 -> 8
+ in x2, USBIN ;1 <-- sample bit 3, timing: edge + {2, 6} cycles
+ eor x1, x2 ;1
+ ror x1 ;1
+ ror shift ;1
+ ser x3 ;1
+ nop ;1
+ rjmp rxbit4 ;2 -> 8
+
+shortcutToStart: ;{,43} into next frame: max 5.5 sync bits missed
+#if !USB_CFG_SAMPLE_EXACT
+ ldi x1, 5 ;2 setup timeout
+#endif
+waitForJ1:
+ sbis USBIN, USBMINUS ;1 wait for D- == 1
+ rjmp waitForJ1 ;2
+#if USB_CFG_SAMPLE_EXACT
+;The following code represents the unrolled loop in the else branch. It
+;results in a sampling window of 1/4 bit which meets the spec.
+ sbis USBIN, USBMINUS
+ rjmp foundK1
+ sbis USBIN, USBMINUS
+ rjmp foundK1
+ sbis USBIN, USBMINUS
+ rjmp foundK1
+ nop
+ nop2
+foundK1:
+#else
+waitForK1:
+ dec x1 ;1
+ sbic USBIN, USBMINUS ;1 wait for D- == 0
+ brne waitForK1 ;2
+#endif
+ pop YH ;2 correct stack alignment
+ nop2 ;2 delay for the same time as the pushes in the original code
+ rjmp shortcutEntry ;2
+
+; ################# receiver loop #################
+; extra jobs done during bit interval:
+; bit 6: se0 check
+; bit 7: or, store, clear
+; bit 0: recover from delay [SE0 is unreliable here due to bit dribbling in hubs]
+; bit 1: se0 check
+; bit 2: se0 check
+; bit 3: overflow check
+; bit 4: se0 check
+; bit 5: rjmp
+
+; stuffed* helpers have the functionality of a subroutine, but we can't afford
+; the overhead of a call. We therefore need a separate routine for each caller
+; which jumps back appropriately.
+
+stuffed5: ;1 for branch taken
+ in x2, USBIN ;1 <-- sample @ +1
+ andi x2, USBMASK ;1
+ breq se0a ;1
+ andi x3, 0xc0 ;1 (0xff03 >> 2) & 0xff
+ ori shift, 0xfc ;1
+ rjmp rxbit6 ;2
+
+stuffed6: ;1 for branch taken
+ in x1, USBIN ;1 <-- sample @ +1
+ andi x1, USBMASK ;1
+ breq se0a ;1
+ andi x3, 0x81 ;1 (0xff03 >> 1) & 0xff
+ ori shift, 0xfc ;1
+ rjmp rxbit7 ;2
+
+; This is somewhat special because it has to compensate for the delay in bit 7
+stuffed7: ;1 for branch taken
+ andi x1, USBMASK ;1 already sampled by caller
+ breq se0a ;1
+ mov x2, x1 ;1 ensure correct NRZI sequence [we can save andi x3 here]
+ ori shift, 0xfc ;1
+ in x1, USBIN ;1 <-- sample bit 0
+ rjmp unstuffed7 ;2
+
+stuffed0: ;1 for branch taken
+ in x1, USBIN ;1 <-- sample @ +1
+ andi x1, USBMASK ;1
+ breq se0a ;1
+ andi x3, 0xfe ;1 (0xff03 >> 7) & 0xff
+ ori shift, 0xfc ;1
+ rjmp rxbit1 ;2
+
+;-----------------------------
+rxLoop:
+ brlo stuffed5 ;1
+rxbit6:
+ in x1, USBIN ;1 <-- sample bit 6
+ andi x1, USBMASK ;1
+ breq se0a ;1
+ eor x2, x1 ;1
+ ror x2 ;1
+ ror shift ;1
+ cpi shift, 4 ;1
+ brlo stuffed6 ;1
+rxbit7:
+ in x2, USBIN ;1 <-- sample bit 7
+ eor x1, x2 ;1
+ ror x1 ;1
+ ror shift ;1
+ eor x3, shift ;1 x3 is 0 at bit locations we changed, 1 at others
+ st y+, x3 ;2 the eor above reconstructed modified bits and inverted rx data
+ ser x3 ;1
+rxbit0:
+ in x1, USBIN ;1 <-- sample bit 0
+ cpi shift, 4 ;1
+ brlo stuffed7 ;1
+unstuffed7:
+ eor x2, x1 ;1
+ ror x2 ;1
+ ror shift ;1
+ cpi shift, 4 ;1
+ brlo stuffed0 ;1
+rxbit1:
+ in x2, USBIN ;1 <-- sample bit 1
+ andi x2, USBMASK ;1
+se0a: ; enlarge jump range to SE0
+ breq se0 ;1 check for SE0 more often close to start of byte
+ eor x1, x2 ;1
+ ror x1 ;1
+ ror shift ;1
+ cpi shift, 4 ;1
+ brlo stuffed1 ;1
+rxbit2:
+ in x1, USBIN ;1 <-- sample bit 2
+ andi x1, USBMASK ;1
+ breq se0 ;1
+ eor x2, x1 ;1
+ ror x2 ;1
+ ror shift ;1
+ cpi shift, 4 ;1
+ brlo stuffed2 ;1
+rxbit3:
+ in x2, USBIN ;1 <-- sample bit 3
+ eor x1, x2 ;1
+ ror x1 ;1
+ ror shift ;1
+ dec cnt ;1 check for buffer overflow
+ breq overflow ;1
+ cpi shift, 4 ;1
+ brlo stuffed3 ;1
+rxbit4:
+ in x1, USBIN ;1 <-- sample bit 4
+ andi x1, USBMASK ;1
+ breq se0 ;1
+ eor x2, x1 ;1
+ ror x2 ;1
+ ror shift ;1
+ cpi shift, 4 ;1
+ brlo stuffed4 ;1
+rxbit5:
+ in x2, USBIN ;1 <-- sample bit 5
+ eor x1, x2 ;1
+ ror x1 ;1
+ ror shift ;1
+ cpi shift, 4 ;1
+ rjmp rxLoop ;2
+;-----------------------------
+
+stuffed1: ;1 for branch taken
+ in x2, USBIN ;1 <-- sample @ +1
+ andi x2, USBMASK ;1
+ breq se0 ;1
+ andi x3, 0xfc ;1 (0xff03 >> 6) & 0xff
+ ori shift, 0xfc ;1
+ rjmp rxbit2 ;2
+
+stuffed2: ;1 for branch taken
+ in x1, USBIN ;1 <-- sample @ +1
+ andi x1, USBMASK ;1
+ breq se0 ;1
+ andi x3, 0xf8 ;1 (0xff03 >> 5) & 0xff
+ ori shift, 0xfc ;1
+ rjmp rxbit3 ;2
+
+stuffed3: ;1 for branch taken
+ in x2, USBIN ;1 <-- sample @ +1
+ andi x2, USBMASK ;1
+ breq se0 ;1
+ andi x3, 0xf0 ;1 (0xff03 >> 4) & 0xff
+ ori shift, 0xfc ;1
+ rjmp rxbit4 ;2
+
+stuffed4: ;1 for branch taken
+ in x1, USBIN ;1 <-- sample @ +1
+ andi x1, USBMASK ;1
+ breq se0 ;1
+ andi x3, 0xe0 ;1 (0xff03 >> 3) & 0xff
+ ori shift, 0xfc ;1
+ rjmp rxbit5 ;2
+
+;################ end receiver loop ###############
+
+overflow: ; ignore package if buffer overflow
+ rjmp rxDoReturn ; enlarge jump range
+
+;This is the only non-error exit point for the software receiver loop
+;{4, 20} cycles after start of SE0, typically {10, 18} after SE0 start = {-6, 2} from end of SE0
+;next sync starts {16,} cycles after SE0 -> worst case start: +4 from next sync start
+;we don't check any CRCs here because there is no time left.
+se0: ;{-6, 2} from end of SE0 / {,4} into next frame
+ mov cnt, YL ;1 assume buffer in lower 256 bytes of memory
+ lds YL, usbInputBuf ;2 reposition to buffer start
+ sub cnt, YL ;1 length of message
+ ldi x1, 1<<USB_INTR_PENDING_BIT ;1
+ cpi cnt, 3 ;1
+ out USB_INTR_PENDING, x1;1 clear pending intr and check flag later. SE0 must be over. {,10} into next frame
+ brlo rxDoReturn ;1 ensure valid packet size, ignore others
+ ld x1, y ;2 PID
+ ldd x2, y+1 ;2 ADDR + 1 bit endpoint number
+ mov x3, x2 ;1 store for endpoint number
+ andi x2, 0x7f ;1 mask endpoint number bit
+ lds shift, usbDeviceId ;2
+ cpi x1, USBPID_SETUP ;1
+ breq isSetupOrOut ;2 -> 19 = {13, 21} from SE0 end
+ cpi x1, USBPID_OUT ;1
+ breq isSetupOrOut ;2 -> 22 = {16, 24} from SE0 end / {,24} into next frame
+ cpi x1, USBPID_IN ;1
+ breq handleIn ;1
+ cpi x1, USBPID_DATA0 ;1
+ breq isData ;1
+ cpi x1, USBPID_DATA1 ;1
+ brne rxDoReturn ;1 ignore all other PIDs
+isData:
+ lds x2, usbCurrentTok ;2
+ tst x2 ;1
+ breq rxDoReturn ;1 for other device or spontaneous data -- ignore
+ lds x1, usbRxLen ;2
+ cpi x1, 0 ;1
+ brne sendNakAndReti ;1 no buffer space available / {30, 38} from SE0 end
+ sts usbRxLen, cnt ;2 store received data, swap buffers
+ sts usbRxToken, x2 ;2
+ lds x1, usbAppBuf ;2
+ sts usbAppBuf, YL ;2
+ sts usbInputBuf, x1 ;2 buffers now swapped
+ rjmp sendAckAndReti ;2 -> {42, 50} from SE0 end
+
+handleIn: ; {18, 26} from SE0 end
+ cp x2, shift ;1 shift contains our device ID
+ brne rxDoReturn ;1 other device
+#if USB_CFG_HAVE_INTRIN_ENDPOINT
+ sbrc x3, 7 ;2
+ rjmp handleIn1 ;0
+#endif
+ lds cnt, usbTxLen ;2
+ cpi cnt, -1 ;1
+ breq sendNakAndReti ;1 -> {27, 35} from SE0 end
+ ldi x1, -1 ;1
+ sts usbTxLen, x1 ;2 buffer is now free
+ ldi YL, lo8(usbTxBuf) ;1
+ ldi YH, hi8(usbTxBuf) ;1
+ rjmp usbSendAndReti ;2 -> {34, 43} from SE0 end
+
+; Comment about when to set usbTxLen to -1:
+; We should set it back to -1 when we receive the ACK from the host. This would
+; be simple to implement: One static variable which stores whether the last
+; tx was for endpoint 0 or 1 and a compare in the receiver to distinguish the
+; ACK. However, we set it back to -1 immediately when we send the package,
+; assuming that no error occurs and the host sends an ACK. We save one byte
+; RAM this way and avoid potential problems with endless retries. The rest of
+; the driver assumes error-free transfers anyway.
+
+otherOutOrSetup:
+ clr x1
+ sts usbCurrentTok, x1
+rxDoReturn:
+ pop x3 ;2
+ pop YL ;2
+ pop YH ;2
+ rjmp sofError ;2
+
+isSetupOrOut: ; we must be fast here -- a data package may follow / {,24} into next frame
+ cp x2, shift ;1 shift contains our device ID
+ brne otherOutOrSetup ;1 other device -- ignore
+ sts usbCurrentTok, x1 ;2
+#if 0 /* we implement only one rx endpoint */
+ sts usbRxEndp, x3 ;2 only stored if we may have to distinguish endpoints
+#endif
+;A transmission can still have data in the output buffer while we receive a
+;SETUP package with an IN phase. To avoid that the old data is sent as a reply,
+;we abort transmission. ### This mechanism assumes that NO OUT OR SETUP package
+;is ever sent to endpoint 1. We would abort transmission for endpoint 0
+;in this case.
+ ldi x1, -1 ;1
+ sts usbMsgLen, x1 ;2
+ sts usbTxLen, x1 ;2 abort transmission
+ pop x3 ;2
+ pop YL ;2
+ in x1, USB_INTR_PENDING;1
+ sbrc x1, USB_INTR_PENDING_BIT;1 check whether data is already arriving {,41} into next frame
+ rjmp shortcutToStart ;2 save the pops and pushes -- a new interrupt is aready pending
+;If the jump above was not taken, we can be at {,2} into the next frame here
+ pop YH ;2
+sofError: ; error in start of frame -- ignore frame
+ ldi x1, 1<<USB_INTR_PENDING_BIT;1 many int0 events occurred during our processing -- clear pending flag
+ out USB_INTR_PENDING, x1;1
+ pop shift ;2
+ pop cnt ;2
+ pop x2 ;2
+ pop x1 ;2
+ out SREG, x1 ;1
+ pop x1 ;2
+ reti ;4 -> {,21} into next frame -> up to 3 sync bits missed
+
+
+sendNakAndReti: ; 21 cycles until SOP
+ ldi YL, lo8(usbNakBuf) ;1
+ ldi YH, hi8(usbNakBuf) ;1
+ rjmp usbSendToken ;2
+
+sendAckAndReti: ; 19 cycles until SOP
+ ldi YL, lo8(usbAckBuf) ;1
+ ldi YH, hi8(usbAckBuf) ;1
+usbSendToken:
+ ldi cnt, 2 ;1
+;;;;rjmp usbSendAndReti fallthrough
+
+; USB spec says:
+; idle = J
+; J = (D+ = 0), (D- = 1) or USBOUT = 0x01
+; K = (D+ = 1), (D- = 0) or USBOUT = 0x02
+; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles)
+
+;usbSend:
+;pointer to data in 'Y'
+;number of bytes in 'cnt'
+;uses: x1...x4, shift, cnt, Y
+usbSendAndReti: ; SOP starts 16 cycles after call
+ push x4 ;2
+ in x1, USBOUT ;1
+ cbr x1, USBMASK ;1 mask out data bits
+ ori x1, USBIDLE ;1 idle
+ out USBOUT, x1 ;1 prepare idle state
+ ldi x4, USBMASK ;1 exor mask
+ in x2, USBDDR ;1
+ ori x2, USBMASK ;1 set both pins to output
+ out USBDDR, x2 ;1 <-- acquire bus now
+; need not init x2 (bitstuff history) because sync starts with 0
+ ldi shift, 0x80 ;1 sync byte is first byte sent
+ rjmp txLoop ;2 -> 13 + 3 = 16 cycles until SOP
+
+#if USB_CFG_HAVE_INTRIN_ENDPOINT /* placed here due to relative jump range */
+handleIn1:
+ lds cnt, usbTxLen1
+ cpi cnt, -1
+ breq sendNakAndReti
+ ldi x1, -1
+ sts usbTxLen1, x1
+ ldi YL, lo8(usbTxBuf1)
+ ldi YH, hi8(usbTxBuf1)
+ rjmp usbSendAndReti
+#endif
+
+bitstuff0: ;1 (for branch taken)
+ eor x1, x4 ;1
+ ldi x2, 0 ;1
+ out USBOUT, x1 ;1 <-- out
+ rjmp didStuff0 ;2 branch back 2 cycles earlier
+bitstuff1: ;1 (for branch taken)
+ eor x1, x4 ;1
+ ldi x2, 0 ;1
+ sec ;1 set carry so that brsh will not jump
+ out USBOUT, x1 ;1 <-- out
+ rjmp didStuff1 ;2 jump back 1 cycle earler
+bitstuff2: ;1 (for branch taken)
+ eor x1, x4 ;1
+ ldi x2, 0 ;1
+ rjmp didStuff2 ;2 jump back 3 cycles earlier and do out
+bitstuff3: ;1 (for branch taken)
+ eor x1, x4 ;1
+ ldi x2, 0 ;1
+ rjmp didStuff3 ;2 jump back earlier
+
+txLoop:
+ sbrs shift, 0 ;1
+ eor x1, x4 ;1
+ out USBOUT, x1 ;1 <-- out
+ ror shift ;1
+ ror x2 ;1
+didStuff0:
+ cpi x2, 0xfc ;1
+ brsh bitstuff0 ;1
+ sbrs shift, 0 ;1
+ eor x1, x4 ;1
+ ror shift ;1
+ out USBOUT, x1 ;1 <-- out
+ ror x2 ;1
+ cpi x2, 0xfc ;1
+didStuff1:
+ brsh bitstuff1 ;1
+ sbrs shift, 0 ;1
+ eor x1, x4 ;1
+ ror shift ;1
+ ror x2 ;1
+didStuff2:
+ out USBOUT, x1 ;1 <-- out
+ cpi x2, 0xfc ;1
+ brsh bitstuff2 ;1
+ sbrs shift, 0 ;1
+ eor x1, x4 ;1
+ ror shift ;1
+ ror x2 ;1
+didStuff3:
+ cpi x2, 0xfc ;1
+ out USBOUT, x1 ;1 <-- out
+ brsh bitstuff3 ;1
+ nop2 ;2
+ ld x3, y+ ;2
+ sbrs shift, 0 ;1
+ eor x1, x4 ;1
+ out USBOUT, x1 ;1 <-- out
+ ror shift ;1
+ ror x2 ;1
+didStuff4:
+ cpi x2, 0xfc ;1
+ brsh bitstuff4 ;1
+ sbrs shift, 0 ;1
+ eor x1, x4 ;1
+ ror shift ;1
+ out USBOUT, x1 ;1 <-- out
+ ror x2 ;1
+ cpi x2, 0xfc ;1
+didStuff5:
+ brsh bitstuff5 ;1
+ sbrs shift, 0 ;1
+ eor x1, x4 ;1
+ ror shift ;1
+ ror x2 ;1
+didStuff6:
+ out USBOUT, x1 ;1 <-- out
+ cpi x2, 0xfc ;1
+ brsh bitstuff6 ;1
+ sbrs shift, 0 ;1
+ eor x1, x4 ;1
+ ror shift ;1
+ ror x2 ;1
+didStuff7:
+ cpi x2, 0xfc ;1
+ out USBOUT, x1 ;1 <-- out
+ brsh bitstuff7 ;1
+ mov shift, x3 ;1
+ dec cnt ;1
+ brne txLoop ;2 | 1
+ cbr x1, USBMASK ;1 prepare SE0
+ pop x4 ;2
+ out USBOUT, x1 ;1 <-- out SE0
+ ldi cnt, 4 ;1 two bits = 16 cycles
+se0Delay:
+ dec cnt ;1
+ brne se0Delay ;2 | 1
+ ori x1, USBIDLE ;1
+ in x2, USBDDR ;1
+ cbr x2, USBMASK ;1 set both pins to input
+ out USBOUT, x1 ;1 <-- out J (idle)
+ cbr x1, USBMASK ;1 configure no pullup on both pins
+ pop x3 ;2
+ pop YL ;2
+ out USBDDR, x2 ;1 <-- release bus now
+ out USBOUT, x1 ;1 set pullup state
+ pop YH ;2
+ rjmp sofError ;2 [we want to jump to rxDoReturn, but this saves cycles]
+
+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
+bitstuff5: ;1 (for branch taken)
+ eor x1, x4 ;1
+ ldi x2, 0 ;1
+ sec ;1 set carry so that brsh is not taken
+ out USBOUT, x1 ;1 <-- out
+ rjmp didStuff5 ;2 jump back 1 cycle earlier
+bitstuff6: ;1 (for branch taken)
+ eor x1, x4 ;1
+ ldi x2, 0 ;1
+ rjmp didStuff6 ;2 jump back 3 cycles earlier and do out there
+bitstuff7: ;1 (for branch taken)
+ eor x1, x4 ;1
+ ldi x2, 0 ;1
+ rjmp didStuff7 ;2 jump back 4 cycles earlier
+
+; ######################## utility functions ########################
+
+; extern unsigned usbCrc16(unsigned char *data, unsigned char len);
+; data: r24/25
+; len: r22
+; temp variables:
+; r18: data byte
+; r19: bit counter
+; r20/21: polynomial
+; r23: scratch
+; r24/25: crc-sum
+; r26/27=X: ptr
+.global usbCrc16
+usbCrc16:
+ mov XL, r24
+ mov XH, r25
+ ldi r24, 0xff
+ ldi r25, 0xff
+ ldi r20, lo8(0xa001)
+ ldi r21, hi8(0xa001)
+crcByteLoop:
+ subi r22, 1
+ brcs crcReady
+ ld r18, x+
+ ldi r19, 8
+crcBitLoop:
+ mov r23, r18
+ eor r23, r24
+ lsr r25
+ ror r24
+ lsr r18
+ sbrs r23, 0
+ rjmp crcNoXor
+ eor r24, r20
+ eor r25, r21
+crcNoXor:
+ dec r19
+ brne crcBitLoop
+ rjmp crcByteLoop
+crcReady:
+ com r24
+ com r25
+ ret
--- /dev/null
+? usbasp.c
+? usbasp.h
+Index: Makefile.am
+===================================================================
+RCS file: /cvsroot/avrdude/avrdude/Makefile.am,v
+retrieving revision 1.23
+diff -u -r1.23 Makefile.am
+--- Makefile.am 10 Feb 2005 14:54:57 -0000 1.23
++++ Makefile.am 9 Apr 2005 09:04:02 -0000
+@@ -85,6 +85,8 @@
+ stk500.c \
+ stk500.h \
+ stk500_private.h \
++ usbasp.c \
++ usbasp.h \
+ term.c \
+ term.h
+
+Index: avrdude.conf.in
+===================================================================
+RCS file: /cvsroot/avrdude/avrdude/avrdude.conf.in,v
+retrieving revision 1.36
+diff -u -r1.36 avrdude.conf.in
+--- avrdude.conf.in 22 Dec 2004 01:30:30 -0000 1.36
++++ avrdude.conf.in 9 Apr 2005 09:04:10 -0000
+@@ -243,6 +243,12 @@
+ miso = 10;
+ ;
+
++programmer
++ id = "usbasp";
++ desc = "usbasp";
++ type = usbasp;
++;
++
+ # The programming dongle used by the popular Ponyprog
+ # utility. It is almost similar to the STK200 one,
+ # except that there is a LED indicating that the
+@@ -337,7 +343,6 @@
+ miso = 10;
+ ;
+
+-
+ # From the contributor of the "xil" jtag cable:
+ # The "vcc" definition isn't really vcc (the cable gets its power from
+ # the programming circuit) but is necessary to switch one of the
+Index: config_gram.y
+===================================================================
+RCS file: /cvsroot/avrdude/avrdude/config_gram.y,v
+retrieving revision 1.39
+diff -u -r1.39 config_gram.y
+--- config_gram.y 22 Dec 2004 01:52:45 -0000 1.39
++++ config_gram.y 9 Apr 2005 09:04:11 -0000
+@@ -34,6 +34,7 @@
+ #include "pgm.h"
+ #include "stk500.h"
+ #include "avr910.h"
++#include "usbasp.h"
+ #include "butterfly.h"
+ #include "avr.h"
+
+@@ -112,6 +113,7 @@
+ %token K_SIZE
+ %token K_STK500
+ %token K_AVR910
++%token K_USBASP
+ %token K_BUTTERFLY
+ %token K_TYPE
+ %token K_VCC
+@@ -302,6 +304,11 @@
+ }
+ } |
+
++ K_TYPE TKN_EQUAL K_USBASP {
++ {
++ usbasp_initpgm(current_prog);
++ }
++ } |
+ K_TYPE TKN_EQUAL K_BUTTERFLY {
+ {
+ butterfly_initpgm(current_prog);
+Index: configure.ac
+===================================================================
+RCS file: /cvsroot/avrdude/avrdude/configure.ac,v
+retrieving revision 1.22
+diff -u -r1.22 configure.ac
+--- configure.ac 10 Feb 2005 15:39:42 -0000 1.22
++++ configure.ac 9 Apr 2005 09:04:11 -0000
+@@ -104,6 +104,21 @@
+ AC_SUBST(SUBDIRS_AC, $SUBDIRS_AC)
+ AC_SUBST(DIST_SUBDIRS_AC, $DIST_SUBDIRS_AC)
+
++# USB stuff
++AH_TEMPLATE([HAVE_LIBUSB],
++ [Define if USB support is enabled via libusb])
++AC_CHECK_LIB(usb, main, have_libusb=yes)
++if test x$have_libusb = xyes; then
++ case $target in
++ *-*-darwin*)
++ LIBS="$LIBS -lusb -framework CoreFoundation -framework IOKit"
++ ;;
++ *)
++ LIBS="$LIBS -lusb"
++ ;;
++ esac
++ AC_DEFINE([HAVE_LIBUSB])
++fi
+
+ # Find the parallel serial device files based on target system
+ # If a system doesn't have a PC style parallel, mark it as unknown.
+Index: lexer.l
+===================================================================
+RCS file: /cvsroot/avrdude/avrdude/lexer.l,v
+retrieving revision 1.30
+diff -u -r1.30 lexer.l
+--- lexer.l 22 Dec 2004 01:52:45 -0000 1.30
++++ lexer.l 9 Apr 2005 09:04:12 -0000
+@@ -156,6 +156,7 @@
+ size { yylval=NULL; return K_SIZE; }
+ stk500 { yylval=NULL; return K_STK500; }
+ avr910 { yylval=NULL; return K_AVR910; }
++usbasp { yylval=NULL; return K_USBASP; }
+ butterfly { yylval=NULL; return K_BUTTERFLY; }
+ type { yylval=NULL; return K_TYPE; }
+ vcc { yylval=NULL; return K_VCC; }
--- /dev/null
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "avr.h"
+#include "pgm.h"
+#include "usbasp.h"
+
+#ifdef HAVE_LIBUSB
+#include <usb.h> /* this is libusb, see http://libusb.sourceforge.net/ */
+
+extern char * progname;
+extern int do_cycles;
+
+static usb_dev_handle *usbhandle;
+
+/*
+ * wrapper for usb_control_msg call
+ */
+static int usbasp_transmit(unsigned char receive, unsigned char functionid,
+ unsigned char send[4], unsigned char * buffer, int buffersize)
+{
+ int nbytes;
+ nbytes = usb_control_msg(usbhandle,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | (receive << 7),
+ functionid,
+ (send[1] << 8) | send[0],
+ (send[3] << 8) | send[2],
+ buffer, buffersize,
+ 5000);
+ if(nbytes < 0){
+ fprintf(stderr, "%s: error: usbasp_transmit: %s\n", progname, usb_strerror());
+ exit(1);
+ }
+
+ return nbytes;
+}
+
+static int usbasp_open(PROGRAMMER * pgm, char * port)
+{
+ struct usb_bus *bus;
+ struct usb_device *dev = 0;
+
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+ for(bus=usb_busses; bus; bus=bus->next){
+ for(dev=bus->devices; dev; dev=dev->next){
+ if(dev->descriptor.idVendor == USBDEV_VENDOR && dev->descriptor.idProduct == USBDEV_PRODUCT)
+ break;
+ }
+ if(dev)
+ break;
+ }
+ if(!dev){
+ fprintf(stderr, "%s: error: could not find USB device vendor=0x%x product=0x%x\n",
+ progname, USBDEV_VENDOR, USBDEV_PRODUCT);
+ exit(1);
+ }
+
+ usbhandle = usb_open(dev);
+ if(!usbhandle){
+ fprintf(stderr, "%s: error: opening usb device: %s\n",
+ progname, usb_strerror());
+ exit(1);
+ }
+
+ return 0;
+}
+
+
+static void usbasp_close(PROGRAMMER * pgm)
+{
+ unsigned char temp[4];
+ memset(temp, 0, sizeof(temp));
+ usbasp_transmit(1, USBASP_FUNC_DISCONNECT, temp, temp, sizeof(temp));
+
+ usb_close(usbhandle);
+}
+
+
+static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p)
+{
+
+ unsigned char temp[4];
+ memset(temp, 0, sizeof(temp));
+ usbasp_transmit(1, USBASP_FUNC_CONNECT, temp, temp, sizeof(temp));
+
+ usleep(100000);
+
+ pgm->program_enable(pgm, p);
+ return 0;
+}
+
+static void usbasp_disable(PROGRAMMER * pgm)
+{
+ /* Do nothing. */
+
+ return;
+}
+
+static void usbasp_enable(PROGRAMMER * pgm)
+{
+ /* Do nothing. */
+
+ return;
+}
+
+static void usbasp_display(PROGRAMMER * pgm, char * p)
+{
+ return;
+}
+
+
+static int usbasp_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
+ unsigned char res[4])
+{
+ int nbytes =
+ usbasp_transmit(1, USBASP_FUNC_TRANSMIT, cmd, res, sizeof(res));
+
+ if(nbytes != 4){
+ fprintf(stderr, "%s: error: wrong responds size\n",
+ progname);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int usbasp_program_enable(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char res[4];
+ unsigned char cmd[4];
+ memset(cmd, 0, sizeof(cmd));
+ memset(res, 0, sizeof(res));
+
+ cmd[0] = 0;
+
+ int nbytes =
+ usbasp_transmit(1, USBASP_FUNC_ENABLEPROG, cmd, res, sizeof(res));
+
+ if ((nbytes != 1) | (res[0] != 0)) {
+ fprintf(stderr, "%s: error: programm enable: target doesn't answer. %x \n",
+ progname, res[0]);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int usbasp_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char cmd[4];
+ unsigned char res[4];
+
+ if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
+ fprintf(stderr, "chip erase instruction not defined for part \"%s\"\n",
+ p->desc);
+ return -1;
+ }
+
+ memset(cmd, 0, sizeof(cmd));
+
+ avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
+ pgm->cmd(pgm, cmd, res);
+ usleep(p->chip_erase_delay);
+ pgm->initialize(pgm, p);
+
+ return 0;
+}
+
+
+static int usbasp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ int page_size, int n_bytes)
+{
+ int n;
+ unsigned char cmd[4];
+ int address = 0;
+ int wbytes = n_bytes;
+ int blocksize;
+ unsigned char * buffer = m->buf;
+ int function;
+
+ if (strcmp(m->desc, "flash") == 0) {
+ function = USBASP_FUNC_READFLASH;
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ function = USBASP_FUNC_READEEPROM;
+ } else {
+ return -2;
+ }
+
+ while (wbytes) {
+ if (wbytes > USBASP_READBLOCKSIZE) {
+ blocksize = USBASP_READBLOCKSIZE;
+ wbytes -= USBASP_READBLOCKSIZE;
+ } else {
+ blocksize = wbytes;
+ wbytes = 0;
+ }
+
+ cmd[0] = address & 0xFF;
+ cmd[1] = address >> 8;
+
+ n = usbasp_transmit(1, function, cmd, buffer, blocksize);
+
+ if (n != blocksize) {
+ fprintf(stderr, "%s: error: wrong reading bytes %x\n",
+ progname, n);
+ exit(1);
+ }
+
+ buffer += blocksize;
+ address += blocksize;
+
+ report_progress (address, n_bytes, NULL);
+ }
+
+ return n_bytes;
+}
+
+static int usbasp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ int page_size, int n_bytes)
+{
+ int n;
+ unsigned char cmd[4];
+ int address = 0;
+ int wbytes = n_bytes;
+ int blocksize;
+ unsigned char * buffer = m->buf;
+ unsigned char blockflags = USBASP_BLOCKFLAG_FIRST;
+ int function;
+
+ if (strcmp(m->desc, "flash") == 0) {
+ function = USBASP_FUNC_WRITEFLASH;
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ function = USBASP_FUNC_WRITEEEPROM;
+ } else {
+ return -2;
+ }
+
+ while (wbytes) {
+ if (wbytes > USBASP_WRITEBLOCKSIZE) {
+ blocksize = USBASP_WRITEBLOCKSIZE;
+ wbytes -= USBASP_WRITEBLOCKSIZE;
+ } else {
+ blocksize = wbytes;
+ wbytes = 0;
+ blockflags |= USBASP_BLOCKFLAG_LAST;
+ }
+
+ cmd[0] = address & 0xFF;
+ cmd[1] = address >> 8;
+ cmd[2] = page_size & 0xFF;
+ cmd[3] = blockflags;
+ blockflags = 0;
+
+ n = usbasp_transmit(0, function, cmd, buffer, blocksize);
+
+ if (n != blocksize) {
+ fprintf(stderr, "%s: error: wrong count at writing %x\n",
+ progname, n);
+ exit(1);
+ }
+
+
+ buffer += blocksize;
+ address += blocksize;
+
+ report_progress (address, n_bytes, NULL);
+ }
+
+ return n_bytes;
+}
+
+void usbasp_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "usbasp");
+
+ /*
+ * mandatory functions
+ */
+
+ pgm->initialize = usbasp_initialize;
+ pgm->display = usbasp_display;
+ pgm->enable = usbasp_enable;
+ pgm->disable = usbasp_disable;
+ pgm->program_enable = usbasp_program_enable;
+ pgm->chip_erase = usbasp_chip_erase;
+ pgm->cmd = usbasp_cmd;
+ pgm->open = usbasp_open;
+ pgm->close = usbasp_close;
+
+ /*
+ * optional functions
+ */
+
+ pgm->paged_write = usbasp_paged_write;
+ pgm->paged_load = usbasp_paged_load;
+
+}
+
+
+#else /* HAVE_LIBUSB */
+
+extern char * progname;
+
+static int usbasp_nousb_open (struct programmer_t *pgm, char * name)
+{
+ fprintf(stderr, "%s: error: no usb support. please compile again with libusb installed.\n",
+ progname);
+
+ exit(1);
+}
+
+void usbasp_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "usbasp");
+
+ pgm->open = usbasp_nousb_open;
+}
+
+#endif /* HAVE_LIBUSB */
--- /dev/null
+#ifndef __usbasp_h__
+#define __usbasp_h__
+
+#include "avrpart.h"
+
+
+#define USBDEV_VENDOR 0x03eb /* ATMEL */
+#define USBDEV_PRODUCT 0xc7B4 /* USBasp */
+
+#define USBASP_FUNC_CONNECT 1
+#define USBASP_FUNC_DISCONNECT 2
+#define USBASP_FUNC_TRANSMIT 3
+#define USBASP_FUNC_READFLASH 4
+#define USBASP_FUNC_ENABLEPROG 5
+#define USBASP_FUNC_WRITEFLASH 6
+#define USBASP_FUNC_READEEPROM 7
+#define USBASP_FUNC_WRITEEEPROM 8
+
+#define USBASP_BLOCKFLAG_FIRST 1
+#define USBASP_BLOCKFLAG_LAST 2
+
+#define USBASP_READBLOCKSIZE 200
+#define USBASP_WRITEBLOCKSIZE 200
+
+
+void usbasp_initpgm (PROGRAMMER * pgm);
+
+#endif /* __usbasp_h__ */