Add OpenULINK firmware
Build requires SDCC, the Small Device C Compiler.
This commit is contained in:
parent
03e4ae8481
commit
3c3f3c4247
|
@ -0,0 +1,90 @@
|
|||
############################################################################
|
||||
# Copyright (C) 2011 by Martin Schmoelzer #
|
||||
# <martin.schmoelzer@student.tuwien.ac.at> #
|
||||
# #
|
||||
# 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. #
|
||||
############################################################################
|
||||
|
||||
# Define the name of our tools. Some distributions (e. g. Fedora) prefix
|
||||
# the SDCC executables, change this accordingly!
|
||||
PREFIX =
|
||||
|
||||
# Small Device C Compiler: http://sdcc.sourceforge.net/
|
||||
CC = $(PREFIX)-sdcc
|
||||
|
||||
# 8051 assembler, part of the SDCC software package.
|
||||
AS = $(PREFIX)-sdas8051
|
||||
|
||||
# SDCC produces quite messy Intel HEX files. This tool is be used to re-format
|
||||
# those files. It is not required for the firmware download functionality in
|
||||
# the OpenOCD driver, but the resulting file is smaller.
|
||||
PACKIHX = $(PREFIX)-packihx
|
||||
|
||||
# GNU binutils size. Used to print the size of the IHX file generated by SDCC.
|
||||
SIZE = size
|
||||
|
||||
# Source and header directories.
|
||||
SRC_DIR = src
|
||||
INCLUDE_DIR = include
|
||||
|
||||
CODE_SIZE = 0x1B00
|
||||
|
||||
# Starting address of __xdata variables. Since the OpenULINK firmware does not
|
||||
# use any of the isochronous interrupts, we can use the isochronous buffer space
|
||||
# as XDATA memory.
|
||||
XRAM_LOC = 0x2000
|
||||
XRAM_SIZE = 0x0800
|
||||
|
||||
CFLAGS = --std-sdcc99 --opt-code-size --model-small
|
||||
LDFLAGS = --code-loc 0x0000 --code-size $(CODE_SIZE) --xram-loc $(XRAM_LOC) \
|
||||
--xram-size $(XRAM_SIZE) --iram-size 256 --model-small
|
||||
|
||||
# list of base object files
|
||||
OBJECTS = main.rel usb.rel protocol.rel jtag.rel delay.rel USBJmpTb.rel
|
||||
HEADERS = $(INCLUDE_DIR)/main.h \
|
||||
$(INCLUDE_DIR)/usb.h \
|
||||
$(INCLUDE_DIR)/protocol.h \
|
||||
$(INCLUDE_DIR)/jtag.h \
|
||||
$(INCLUDE_DIR)/delay.h \
|
||||
$(INCLUDE_DIR)/reg_ezusb.h \
|
||||
$(INCLUDE_DIR)/io.h \
|
||||
$(INCLUDE_DIR)/msgtypes.h \
|
||||
$(INCLUDE_DIR)/shorttypes.h
|
||||
|
||||
# Disable all built-in rules.
|
||||
.SUFFIXES:
|
||||
|
||||
# Targets which are executed even when identically named file is present.
|
||||
.PHONY: all, clean
|
||||
|
||||
all: ulink_firmware.ihx
|
||||
$(SIZE) ulink_firmware.ihx
|
||||
|
||||
ulink_firmware.ihx: $(OBJECTS)
|
||||
$(CC) -mmcs51 $(LDFLAGS) -o $@ $^
|
||||
|
||||
# Rebuild every C module (there are only 5 of them) if any header changes.
|
||||
%.rel: $(SRC_DIR)/%.c $(HEADERS)
|
||||
$(CC) -c $(CFLAGS) -mmcs51 -I$(INCLUDE_DIR) -o $@ $<
|
||||
|
||||
%.rel: $(SRC_DIR)/%.a51
|
||||
$(AS) -lsgo $@ $<
|
||||
|
||||
clean:
|
||||
rm -f *.asm *.lst *.rel *.rst *.sym *.ihx *.lnk *.map *.mem
|
||||
|
||||
hex: ulink_firmware.ihx
|
||||
$(PACKIHX) ulink_firmware.ihx > ulink_firmware.hex
|
|
@ -0,0 +1,34 @@
|
|||
This is the OpenULINK firmware for the Keil ULINK JTAG adapter.
|
||||
|
||||
The main components of the Keil ULINK adapter are:
|
||||
- Cypress EZ-USB microcontroller: enhanced 8051 CPU + USB core (1.1 Full-Speed)
|
||||
- SRAM memory chip
|
||||
- Level shifters to support different JTAG signal voltage levels
|
||||
- Pin headers for various JTAG pin assignments
|
||||
|
||||
This firmware can only be run on the ORIGINAL Keil ULINK adapter, not on the
|
||||
newer ULINK2, ULINK-ME or ULINK-PRO, as these adapters are based on different
|
||||
hardware.
|
||||
|
||||
To compile the firmware, the SDCC compiler package is required. Most Linux
|
||||
distributions include SDCC in their official package repositories. The SDCC
|
||||
source code can be found at http://sdcc.sourceforge.net/
|
||||
Simply type "make hex" in the OpenULINK directory to compile the firmware.
|
||||
"make clean" will remove all generated files except the Intel HEX file required
|
||||
for downloading the firmware to the ULINK adapter.
|
||||
|
||||
Note that the EZ-USB microcontroller does not have on-chip flash, nor does the
|
||||
Keil ULINK include on-board memory to store the firmware program of the EZ-USB.
|
||||
Instead, upon initial connection of the ULINK adapter to the host PC via USB,
|
||||
the EZ-USB core has enough intelligence to act as a stand-alone USB device,
|
||||
responding to USB control requests and allowing firmware download via a special
|
||||
VENDOR-type control request. Then, the EZ-USB microcontroller simulates a
|
||||
disconnect and re-connect to the USB bus. It may take up to two seconds for the
|
||||
host to recognize the newly connected device before OpenOCD can proceed to
|
||||
execute JTAG commands. This delay is only visible when OpenOCD first uses a
|
||||
blank (unconfigured) ULINK device.
|
||||
|
||||
Once the user disconnects the ULINK adapter, all its memory contents are lost
|
||||
and the firmware download process has to be executed again. This also maintains
|
||||
compatibility with the original Keil uVision IDE, which will happily download
|
||||
its own firmware image to a blank ULINK adapter.
|
|
@ -0,0 +1,26 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Martin Schmoelzer *
|
||||
* <martin.schmoelzer@student.tuwien.ac.at> *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __COMMON_H
|
||||
#define __COMMON_H
|
||||
|
||||
#define DIV_ROUND_UP(m, n) (((m) + (n) - 1) / (n))
|
||||
|
||||
#endif
|
|
@ -0,0 +1,34 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Martin Schmoelzer *
|
||||
* <martin.schmoelzer@student.tuwien.ac.at> *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __DELAY_H
|
||||
#define __DELAY_H
|
||||
|
||||
#include "shorttypes.h"
|
||||
|
||||
#define NOP {__asm nop __endasm;}
|
||||
|
||||
void delay_5us(void);
|
||||
void delay_1ms(void);
|
||||
|
||||
void delay_us(u16 delay);
|
||||
void delay_ms(u16 delay);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,125 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Martin Schmoelzer *
|
||||
* <martin.schmoelzer@student.tuwien.ac.at> *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __IO_H
|
||||
#define __IO_H
|
||||
|
||||
#include "reg_ezusb.h"
|
||||
|
||||
/***************************************************************************
|
||||
* JTAG Signals: *
|
||||
***************************************************************************
|
||||
* TMS ....... Test Mode Select *
|
||||
* TCK ....... Test Clock *
|
||||
* TDI ....... Test Data Input (from device point of view, not JTAG *
|
||||
* adapter point of view!) *
|
||||
* TDO ....... Test Data Output (from device point of view, not JTAG *
|
||||
* adapter point of view!) *
|
||||
* TRST ...... Test Reset: Used to reset the TAP Finite State Machine *
|
||||
* into the Test Logic Reset state *
|
||||
* RTCK ...... Return Test Clock *
|
||||
* OCDSE ..... Enable/Disable OCDS interface (Infineon specific) - shared *
|
||||
* with /JEN *
|
||||
* TRAP ...... Trap Condition (Infineon specific) - shared with TSTAT *
|
||||
* BRKIN ..... Hardware Break-In (Infineon specific) *
|
||||
* BRKOUT .... Hardware Break-Out (Infineon specific) *
|
||||
* /JEN ...... JTAG-Enable (STMicroelectronics specific) - shared *
|
||||
* with OCDSE *
|
||||
* TSTAT ..... JTAG ISP Status (STMicroelectronics specific) - shared *
|
||||
* with TRAP *
|
||||
* RESET ..... Chip Reset (STMicroelectronics specific) *
|
||||
* /TERR ..... JTAG ISP Error (STMicroelectronics specific) - shared *
|
||||
* with BRKOUT *
|
||||
***************************************************************************/
|
||||
|
||||
/* PORT A */
|
||||
#define PIN_U_OE OUTA0
|
||||
// PA1 Not Connected
|
||||
#define PIN_OE OUTA2
|
||||
// PA3 Not Connected
|
||||
#define PIN_RUN_LED OUTA4
|
||||
#define PIN_TDO PINA5
|
||||
#define PIN_BRKOUT PINA6
|
||||
#define PIN_COM_LED OUTA7
|
||||
|
||||
|
||||
/* PORT B */
|
||||
#define PIN_TDI OUTB0
|
||||
#define PIN_TMS OUTB1
|
||||
#define PIN_TCK OUTB2
|
||||
#define PIN_TRST OUTB3
|
||||
#define PIN_BRKIN OUTB4
|
||||
#define PIN_RESET OUTB5
|
||||
#define PIN_OCDSE OUTB6
|
||||
#define PIN_TRAP PINB7
|
||||
|
||||
/* JTAG Signals with direction 'OUT' on port B */
|
||||
#define MASK_PORTB_DIRECTION_OUT (PIN_TDI | PIN_TMS | PIN_TCK | PIN_TRST | PIN_BRKIN | PIN_RESET | PIN_OCDSE)
|
||||
|
||||
/* PORT C */
|
||||
#define PIN_RXD0 PINC0
|
||||
#define PIN_TXD0 OUTC1
|
||||
#define PIN_RESET_2 PINC2
|
||||
// PC3 Not Connected
|
||||
// PC4 Not Connected
|
||||
#define PIN_RTCK PINC5
|
||||
#define PIN_WR OUTC6
|
||||
// PC7 Not Connected
|
||||
|
||||
/* LED Macros */
|
||||
#define SET_RUN_LED() OUTA &= ~PIN_RUN_LED
|
||||
#define CLEAR_RUN_LED() OUTA |= PIN_RUN_LED
|
||||
|
||||
#define SET_COM_LED() OUTA &= ~PIN_COM_LED
|
||||
#define CLEAR_COM_LED() OUTA |= PIN_COM_LED
|
||||
|
||||
/* JTAG Pin Macros */
|
||||
#define GET_TMS() (PINSB & PIN_TMS)
|
||||
#define GET_TCK() (PINSB & PIN_TCK)
|
||||
|
||||
#define GET_TDO() (PINSA & PIN_TDO)
|
||||
#define GET_BRKOUT() (PINSA & PIN_BRKOUT)
|
||||
#define GET_TRAP() (PINSB & PIN_TRAP)
|
||||
#define GET_RTCK() (PINSC & PIN_RTCK)
|
||||
|
||||
#define SET_TMS_HIGH() OUTB |= PIN_TMS
|
||||
#define SET_TMS_LOW() OUTB &= ~PIN_TMS
|
||||
|
||||
#define SET_TCK_HIGH() OUTB |= PIN_TCK
|
||||
#define SET_TCK_LOW() OUTB &= ~PIN_TCK
|
||||
|
||||
#define SET_TDI_HIGH() OUTB |= PIN_TDI
|
||||
#define SET_TDI_LOW() OUTB &= ~PIN_TDI
|
||||
|
||||
/* TRST and RESET are low-active and inverted by hardware. SET_HIGH de-asserts
|
||||
* the signal (enabling reset), SET_LOW asserts the signal (disabling reset) */
|
||||
#define SET_TRST_HIGH() OUTB |= PIN_TRST
|
||||
#define SET_TRST_LOW() OUTB &= ~PIN_TRST
|
||||
|
||||
#define SET_RESET_HIGH() OUTB |= PIN_RESET
|
||||
#define SET_RESET_LOW() OUTB &= ~PIN_RESET
|
||||
|
||||
#define SET_OCDSE_HIGH() OUTB |= PIN_OCDSE
|
||||
#define SET_OCDSE_LOW() OUTB &= ~PIN_OCDSE
|
||||
|
||||
#define SET_BRKIN_HIGH() OUTB |= PIN_BRKIN
|
||||
#define SET_BRKIN_LOW() OUTB &= ~PIN_BRKIN
|
||||
|
||||
#endif
|
|
@ -0,0 +1,46 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Martin Schmoelzer *
|
||||
* <martin.schmoelzer@student.tuwien.ac.at> *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __JTAG_H
|
||||
#define __JTAG_H
|
||||
|
||||
#include "shorttypes.h"
|
||||
|
||||
#define NOP {__asm nop __endasm;}
|
||||
|
||||
void jtag_scan_in(u8 out_offset, u8 in_offset);
|
||||
void jtag_scan_out(u8 out_offset);
|
||||
void jtag_scan_io(u8 out_offset, u8 in_offset);
|
||||
|
||||
void jtag_slow_scan_in(u8 scan_size_bytes, u8 tdo_index, u8 scan_options);
|
||||
void jtag_slow_scan_out(u8 scan_size_bytes, u8 tdi_index, u8 scan_options);
|
||||
void jtag_slow_scan_io(u8 scan_size_bytes, u8 tdi_index, u8 tdo_index,
|
||||
u8 scan_options);
|
||||
|
||||
void jtag_clock_tck(u16 count);
|
||||
void jtag_clock_tms(u8 count, u8 sequence);
|
||||
void jtag_slow_clock_tms(u8 count, u8 sequence);
|
||||
|
||||
u16 jtag_get_signals(void);
|
||||
void jtag_set_signals(u8 low, u8 high);
|
||||
|
||||
void jtag_configure_tck_delay(u8 scan, u8 tck, u8 tms);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,26 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Martin Schmoelzer *
|
||||
* <martin.schmoelzer@student.tuwien.ac.at> *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __MAIN_H
|
||||
#define __MAIN_H
|
||||
|
||||
void io_init(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,187 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Martin Schmoelzer *
|
||||
* <martin.schmoelzer@student.tuwien.ac.at> *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
/**
|
||||
* @file Definition of the commands supported by the OpenULINK firmware.
|
||||
*
|
||||
* Basically, two types of commands can be distinguished:
|
||||
* - Commands with fixed payload size
|
||||
* - Commands with variable payload size
|
||||
*
|
||||
* SCAN commands (in all variations) carry payloads of variable size, all
|
||||
* other commands carry payloads of fixed size.
|
||||
*
|
||||
* In the case of SCAN commands, the payload size (n) is calculated by
|
||||
* dividing the scan_size_bits variable by 8, rounding up the result.
|
||||
*
|
||||
* Offset zero always contains the command ID.
|
||||
*
|
||||
****************************************************************************
|
||||
* CMD_SCAN_IN, CMD_SLOW_SCAN_IN: *
|
||||
* *
|
||||
* OUT: *
|
||||
* offset 1: scan_size_bytes *
|
||||
* offset 2: bits_last_byte *
|
||||
* offset 3: tms_count_start + tms_count_end *
|
||||
* offset 4: tms_sequence_start *
|
||||
* offset 5: tms_sequence_end *
|
||||
* *
|
||||
* IN: *
|
||||
* offset 0..n: TDO data *
|
||||
****************************************************************************
|
||||
* CMD_SCAN_OUT, CMD_SLOW_SCAN_OUT: *
|
||||
* *
|
||||
* OUT: *
|
||||
* offset 1: scan_size_bytes *
|
||||
* offset 2: bits_last_byte *
|
||||
* offset 3: tms_count_start + tms_count_end *
|
||||
* offset 4: tms_sequence_start *
|
||||
* offset 5: tms_sequence_end *
|
||||
* offset 6..x: TDI data *
|
||||
****************************************************************************
|
||||
* CMD_SCAN_IO, CMD_SLOW_SCAN_IO: *
|
||||
* *
|
||||
* OUT: *
|
||||
* offset 1: scan_size_bytes *
|
||||
* offset 2: bits_last_byte *
|
||||
* offset 3: tms_count_start + tms_count_end *
|
||||
* offset 4: tms_sequence_start *
|
||||
* offset 5: tms_sequence_end *
|
||||
* offset 6..x: TDI data *
|
||||
* *
|
||||
* IN: *
|
||||
* offset 0..n: TDO data *
|
||||
****************************************************************************
|
||||
* CMD_CLOCK_TMS, CMD_SLOW_CLOCK_TMS: *
|
||||
* *
|
||||
* OUT: *
|
||||
* offset 1: tms_count *
|
||||
* offset 2: tms_sequence *
|
||||
****************************************************************************
|
||||
* CMD_CLOCK_TCK: *
|
||||
* *
|
||||
* OUT: *
|
||||
* offset 1: low byte of tck_count *
|
||||
* offset 2: high byte of tck_count *
|
||||
****************************************************************************
|
||||
* CMD_CLOCK_SLEEP_US: *
|
||||
* *
|
||||
* OUT: *
|
||||
* offset 1: low byte of sleep_us *
|
||||
* offset 2: high byte of sleep_us *
|
||||
****************************************************************************
|
||||
* CMD_CLOCK_SLEEP_MS: *
|
||||
* *
|
||||
* OUT: *
|
||||
* offset 1: low byte of sleep_ms *
|
||||
* offset 2: high byte of sleep_ms *
|
||||
****************************************************************************
|
||||
* CMD_GET_SIGNALS: *
|
||||
* *
|
||||
* IN: *
|
||||
* offset 0: current state of input signals *
|
||||
* offset 1: current state of output signals *
|
||||
****************************************************************************
|
||||
* CMD_SET_SIGNALS: *
|
||||
* *
|
||||
* OUT: *
|
||||
* offset 1: signals that should be de-asserted *
|
||||
* offset 2: signals that should be asserted *
|
||||
****************************************************************************
|
||||
* CMD_CONFIGURE_TCK_FREQ: *
|
||||
* *
|
||||
* OUT: *
|
||||
* offset 1: delay value for scan functions *
|
||||
* offset 2: delay value for clock_tck function *
|
||||
* offset 3: delay value for clock_tms function *
|
||||
****************************************************************************
|
||||
* CMD_SET_LEDS: *
|
||||
* *
|
||||
* OUT: *
|
||||
* offset 1: LED states: *
|
||||
* Bit 0: turn COM LED on *
|
||||
* Bit 1: turn RUN LED on *
|
||||
* Bit 2: turn COM LED off *
|
||||
* Bit 3: turn RUN LED off *
|
||||
* Bits 7..4: Reserved *
|
||||
****************************************************************************
|
||||
* CMD_TEST: *
|
||||
* *
|
||||
* OUT: *
|
||||
* offset 1: unused dummy value *
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __MSGTYPES_H
|
||||
#define __MSGTYPES_H
|
||||
|
||||
/*
|
||||
* Command IDs:
|
||||
*
|
||||
* Bits 7..6: Reserved, should always be zero
|
||||
* Bits 5..0: Command ID. There are 62 usable IDs. Of this 63 available IDs,
|
||||
* the IDs 0x00..0x1F are commands with variable payload size,
|
||||
* the IDs 0x20..0x3F are commands with fixed payload size.
|
||||
*/
|
||||
|
||||
#define CMD_ID_MASK 0x3F
|
||||
|
||||
/* Commands with variable payload size */
|
||||
#define CMD_SCAN_IN 0x00
|
||||
#define CMD_SLOW_SCAN_IN 0x01
|
||||
#define CMD_SCAN_OUT 0x02
|
||||
#define CMD_SLOW_SCAN_OUT 0x03
|
||||
#define CMD_SCAN_IO 0x04
|
||||
#define CMD_SLOW_SCAN_IO 0x05
|
||||
|
||||
/* Commands with fixed payload size */
|
||||
#define CMD_CLOCK_TMS 0x20
|
||||
#define CMD_SLOW_CLOCK_TMS 0x21
|
||||
#define CMD_CLOCK_TCK 0x22
|
||||
#define CMD_SLEEP_US 0x23
|
||||
#define CMD_SLEEP_MS 0x24
|
||||
#define CMD_GET_SIGNALS 0x25
|
||||
#define CMD_SET_SIGNALS 0x26
|
||||
#define CMD_CONFIGURE_TCK_FREQ 0x27
|
||||
#define CMD_SET_LEDS 0x28
|
||||
#define CMD_TEST 0x29
|
||||
|
||||
/* JTAG signal definition for jtag_get_signals() -- Input signals! */
|
||||
#define SIGNAL_TDO (1<<0)
|
||||
#define SIGNAL_BRKOUT (1<<1)
|
||||
#define SIGNAL_TRAP (1<<2)
|
||||
#define SIGNAL_RTCK (1<<3)
|
||||
|
||||
/* JTAG signal definition for jtag_get_signals() -- Output signals! */
|
||||
#define SIGNAL_TDI (1<<0)
|
||||
#define SIGNAL_TMS (1<<1)
|
||||
#define SIGNAL_TCK (1<<2)
|
||||
#define SIGNAL_TRST (1<<3)
|
||||
#define SIGNAL_BRKIN (1<<4)
|
||||
#define SIGNAL_RESET (1<<5)
|
||||
#define SIGNAL_OCDSE (1<<6)
|
||||
|
||||
/* LED definitions for CMD_SET_LEDS and CMD_CLEAR_LEDS commands */
|
||||
#define COM_LED_ON (1<<0)
|
||||
#define RUN_LED_ON (1<<1)
|
||||
#define COM_LED_OFF (1<<2)
|
||||
#define RUN_LED_OFF (1<<3)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,33 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Martin Schmoelzer *
|
||||
* <martin.schmoelzer@student.tuwien.ac.at> *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __PROTOCOL_H
|
||||
#define __PROTOCOL_H
|
||||
|
||||
#include "shorttypes.h"
|
||||
#include "common.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
void execute_set_led_command(void);
|
||||
|
||||
bool execute_command(void);
|
||||
void command_loop(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,742 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Martin Schmoelzer *
|
||||
* <martin.schmoelzer@student.tuwien.ac.at> *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef REG_EZUSB_H
|
||||
#define REG_EZUSB_H
|
||||
|
||||
/**
|
||||
* @file All information in this file was taken from the EZ-USB Technical
|
||||
* Reference Manual, Cypress Semiconductor, 3901 North First Street
|
||||
* San Jose, CA 95134 (www.cypress.com).
|
||||
*
|
||||
* The EZ-USB Technical Reference Manual is called "EZ-USB TRM" hereafter.
|
||||
*
|
||||
* The following bit name definitions differ from those in the EZ-USB TRM:
|
||||
* - All lowercase characters in the EZ-USB TRM bit names have been converted
|
||||
* to capitals (e. g. "WakeSRC" converted to "WAKESRC").
|
||||
* - CPUCS: 8051RES is named "RES8051".
|
||||
* - ISOCTL: Two MBZ ("Must Be Zero") bits are named "MBZ0" and "MBZ1".
|
||||
* - I2CS: STOP and START bits are preceded by "I2C_"
|
||||
* - INxCS, OUTxCS: the busy and stall bits are named "EPBSY" and "EPSTALL".
|
||||
* - TOGCTL: EZ-USB TRM bit names are preceded by "TOG_".
|
||||
*/
|
||||
|
||||
/* Compiler-specific definitions of SBIT, SFR, SFRX, ... macros */
|
||||
#include <mcs51/compiler.h>
|
||||
|
||||
/* Bit vectors */
|
||||
#define bmBit0 0x01
|
||||
#define bmBit1 0x02
|
||||
#define bmBit2 0x04
|
||||
#define bmBit3 0x08
|
||||
#define bmBit4 0x10
|
||||
#define bmBit5 0x20
|
||||
#define bmBit6 0x40
|
||||
#define bmBit7 0x80
|
||||
|
||||
/***************************************************************************/
|
||||
/************************ Special Function Registers ***********************/
|
||||
/***************************************************************************/
|
||||
|
||||
/* See EZ-USB TRM, pp. A-9 - A-10 */
|
||||
|
||||
SFR(SP, 0x81);
|
||||
SFR(DPL0, 0x82);
|
||||
SFR(DPH0, 0x83);
|
||||
SFR(DPL1, 0x84);
|
||||
SFR(DPL2, 0x85);
|
||||
|
||||
SFR(DPS, 0x86);
|
||||
#define SEL bmBit0
|
||||
// Bit 1 read-only, always reads '0'
|
||||
// Bit 2 read-only, always reads '0'
|
||||
// Bit 3 read-only, always reads '0'
|
||||
// Bit 4 read-only, always reads '0'
|
||||
// Bit 5 read-only, always reads '0'
|
||||
// Bit 6 read-only, always reads '0'
|
||||
// Bit 7 read-only, always reads '0'
|
||||
|
||||
SFR(PCON, 0x87);
|
||||
#define IDLE bmBit0
|
||||
#define STOP bmBit1
|
||||
#define GF0 bmBit2
|
||||
#define GF1 bmBit3
|
||||
// Bit 4 read-only, always reads '1'
|
||||
// Bit 5 read-only, always reads '1'
|
||||
// Bit 6 unused
|
||||
#define SMOD0 bmBit7
|
||||
|
||||
SFR(TCON, 0x88);
|
||||
SBIT(IT0, 0x88, 0);
|
||||
SBIT(IE0, 0x88, 1);
|
||||
SBIT(IT1, 0x88, 2);
|
||||
SBIT(IE1, 0x88, 3);
|
||||
SBIT(TR0, 0x88, 4);
|
||||
SBIT(TF0, 0x88, 5);
|
||||
SBIT(TR1, 0x88, 6);
|
||||
SBIT(TF1, 0x88, 7);
|
||||
|
||||
SFR(TMOD, 0x89);
|
||||
/* Some bits in this register share the same name in the EZ-USB TRM. Therefore,
|
||||
* we add a '0'/'1' to distinguish them */
|
||||
#define M00 bmBit0
|
||||
#define M01 bmBit1
|
||||
#define CT0 bmBit2
|
||||
#define GATE0 bmBit3
|
||||
#define M10 bmBit4
|
||||
#define M11 bmBit5
|
||||
#define CT1 bmBit6
|
||||
#define GATE1 bmBit7
|
||||
|
||||
SFR(TL0, 0x8A);
|
||||
SFR(TL1, 0x8B);
|
||||
SFR(TH0, 0x8C);
|
||||
SFR(TH1, 0x8D);
|
||||
|
||||
SFR(CKCON, 0x8E);
|
||||
#define MD0 bmBit0
|
||||
#define MD1 bmBit1
|
||||
#define MD2 bmBit2
|
||||
#define T0M bmBit3
|
||||
#define T1M bmBit4
|
||||
#define T2M bmBit5
|
||||
// Bit 6 unused
|
||||
// Bit 7 unused
|
||||
|
||||
SFR(SPC_FNC, 0x8D);
|
||||
#define bmWRS bmBit0
|
||||
// Bit 1 read-only, always reads '0'
|
||||
// Bit 2 read-only, always reads '0'
|
||||
// Bit 3 read-only, always reads '0'
|
||||
// Bit 4 read-only, always reads '0'
|
||||
// Bit 5 read-only, always reads '0'
|
||||
// Bit 6 read-only, always reads '0'
|
||||
// Bit 7 read-only, always reads '0'
|
||||
|
||||
SFR(EXIF, 0x91);
|
||||
// Bit 0 read-only, always reads '0'
|
||||
// Bit 1 read-only, always reads '0'
|
||||
// Bit 2 read-only, always reads '0'
|
||||
// Bit 3 read-only, always reads '1'
|
||||
#define USBINT bmBit4
|
||||
#define I2CINT bmBit5
|
||||
#define IE4 bmBit6
|
||||
#define IE5 bmBit7
|
||||
|
||||
/* Definition of the _XPAGE register, according to SDCC Compiler User Guide,
|
||||
* Version 3.0.1, Chapter 4, p. 61. Also see EZ-USB TRM, p. 2-4. */
|
||||
SFR(MPAGE, 0x92);
|
||||
SFR(_XPAGE, 0x92);
|
||||
|
||||
SFR(SCON0, 0x98);
|
||||
SBIT(RI_0, 0x98, 0);
|
||||
SBIT(TI_0, 0x98, 1);
|
||||
SBIT(RB8_0, 0x98, 2);
|
||||
SBIT(TB8_0, 0x98, 3);
|
||||
SBIT(REN_0, 0x98, 4);
|
||||
SBIT(SM2_0, 0x98, 5);
|
||||
SBIT(SM1_0, 0x98, 6);
|
||||
SBIT(SM0_0, 0x98, 7);
|
||||
|
||||
SFR(SBUF0, 0x99);
|
||||
|
||||
SFR(IE, 0xA8);
|
||||
SBIT(EX0, 0xA8, 0);
|
||||
SBIT(ET0, 0xA8, 1);
|
||||
SBIT(EX1, 0xA8, 2);
|
||||
SBIT(ET1, 0xA8, 3);
|
||||
SBIT(ES0, 0xA8, 4);
|
||||
SBIT(ET2, 0xA8, 5);
|
||||
SBIT(ES1, 0xA8, 6);
|
||||
SBIT(EA, 0xA8, 7);
|
||||
|
||||
SFR(IP, 0xB8);
|
||||
SBIT(PX0, 0xB8, 0);
|
||||
SBIT(PT0, 0xB8, 1);
|
||||
SBIT(PX1, 0xB8, 2);
|
||||
SBIT(PT1, 0xB8, 3);
|
||||
SBIT(PS0, 0xB8, 4);
|
||||
SBIT(PT2, 0xB8, 5);
|
||||
SBIT(PS1, 0xB8, 6);
|
||||
// Bit 7 read-only, always reads '1'
|
||||
|
||||
SFR(SCON1, 0xC0);
|
||||
SBIT(RI_1, 0xC0, 0);
|
||||
SBIT(TI_1, 0xC0, 1);
|
||||
SBIT(RB8_1, 0xC0, 2);
|
||||
SBIT(TB8_1, 0xC0, 3);
|
||||
SBIT(REN_1, 0xC0, 4);
|
||||
SBIT(SM2_1, 0xC0, 5);
|
||||
SBIT(SM1_1, 0xC0, 6);
|
||||
SBIT(SM0_1, 0xC0, 7);
|
||||
|
||||
SFR(SBUF1, 0xC1);
|
||||
|
||||
SFR(T2CON, 0xC8);
|
||||
SBIT(CPRL2, 0xC8, 0);
|
||||
SBIT(CT2, 0xC8, 1);
|
||||
SBIT(TR2, 0xC8, 2);
|
||||
SBIT(EXEN2, 0xC8, 3);
|
||||
SBIT(TCLK, 0xC8, 4);
|
||||
SBIT(RCLK, 0xC8, 5);
|
||||
SBIT(EXF2, 0xC8, 6);
|
||||
SBIT(TF2, 0xC8, 7);
|
||||
|
||||
SFR(RCAP2L, 0xCA);
|
||||
SFR(RCAP2H, 0xCB);
|
||||
SFR(TL2, 0xCC);
|
||||
SFR(TH2, 0xCD);
|
||||
|
||||
SFR(PSW, 0xD0);
|
||||
SBIT(P, 0xD0, 0);
|
||||
SBIT(F1, 0xD0, 1);
|
||||
SBIT(OV, 0xD0, 2);
|
||||
SBIT(RS0, 0xD0, 3);
|
||||
SBIT(RS1, 0xD0, 4);
|
||||
SBIT(F0, 0xD0, 5);
|
||||
SBIT(AC, 0xD0, 6);
|
||||
SBIT(CY, 0xD0, 7);
|
||||
|
||||
SFR(EICON, 0xD8);
|
||||
// Bit 0 read-only, always reads '0'
|
||||
// Bit 1 read-only, always reads '0'
|
||||
// Bit 2 read-only, always reads '0'
|
||||
SBIT(INT6, 0xD8, 3);
|
||||
SBIT(RESI, 0xD8, 4);
|
||||
SBIT(ERESI, 0xD8, 5);
|
||||
// Bit 6 read-only, always reads '1'
|
||||
SBIT(SMOD1, 0xD8, 7);
|
||||
|
||||
SFR(ACC, 0xE0);
|
||||
|
||||
SFR(EIE, 0xE8);
|
||||
SBIT(EUSB, 0xE8, 0);
|
||||
SBIT(EI2C, 0xE8, 1);
|
||||
SBIT(EX4, 0xE8, 2);
|
||||
SBIT(EX5, 0xE8, 3);
|
||||
SBIT(EWDI, 0xE8, 4);
|
||||
// Bit 5 read-only, always reads '1'
|
||||
// Bit 6 read-only, always reads '1'
|
||||
// Bit 7 read-only, always reads '1'
|
||||
|
||||
SFR(B, 0xF0);
|
||||
|
||||
SFR(EIP, 0xF8);
|
||||
SBIT(PUSB, 0xF8, 0);
|
||||
SBIT(PI2C, 0xF8, 1);
|
||||
SBIT(PX4, 0xF8, 2);
|
||||
SBIT(PX5, 0xF8, 3);
|
||||
SBIT(PX6, 0xF8, 4);
|
||||
// Bit 5 read-only, always reads '1'
|
||||
// Bit 6 read-only, always reads '1'
|
||||
// Bit 7 read-only, always reads '1'
|
||||
|
||||
/***************************************************************************/
|
||||
/***************************** XDATA Registers *****************************/
|
||||
/***************************************************************************/
|
||||
|
||||
/************************ Endpoint 0-7 Data Buffers ************************/
|
||||
SFRX(OUT7BUF[64], 0x7B40);
|
||||
SFRX(IN7BUF[64], 0x7B80);
|
||||
SFRX(OUT6BUF[64], 0x7BC0);
|
||||
SFRX(IN6BUF[64], 0x7C00);
|
||||
SFRX(OUT5BUF[64], 0x7C40);
|
||||
SFRX(IN5BUF[64], 0x7C80);
|
||||
SFRX(OUT4BUF[64], 0x7CC0);
|
||||
SFRX(IN4BUF[64], 0x7D00);
|
||||
SFRX(OUT3BUF[64], 0x7D40);
|
||||
SFRX(IN3BUF[64], 0x7D80);
|
||||
SFRX(OUT2BUF[64], 0x7DC0);
|
||||
SFRX(IN2BUF[64], 0x7E00);
|
||||
SFRX(OUT1BUF[64], 0x7E40);
|
||||
SFRX(IN1BUF[64], 0x7E80);
|
||||
SFRX(OUT0BUF[64], 0x7EC0);
|
||||
SFRX(IN0BUF[64], 0x7F00);
|
||||
// 0x7F40 - 0x7F5F reserved
|
||||
|
||||
/**************************** Isochronous Data *****************************/
|
||||
SFRX(OUT8DATA, 0x7F60);
|
||||
SFRX(OUT9DATA, 0x7F61);
|
||||
SFRX(OUT10DATA, 0x7F62);
|
||||
SFRX(OUT11DATA, 0x7F63);
|
||||
SFRX(OUT12DATA, 0x7F64);
|
||||
SFRX(OUT13DATA, 0x7F65);
|
||||
SFRX(OUT14DATA, 0x7F66);
|
||||
SFRX(OUT15DATA, 0x7F67);
|
||||
|
||||
SFRX(IN8DATA, 0x7F68);
|
||||
SFRX(IN9DATA, 0x7F69);
|
||||
SFRX(IN10DATA, 0x7F6A);
|
||||
SFRX(IN11DATA, 0x7F6B);
|
||||
SFRX(IN12DATA, 0x7F6C);
|
||||
SFRX(IN13DATA, 0x7F6D);
|
||||
SFRX(IN14DATA, 0x7F6E);
|
||||
SFRX(IN15DATA, 0x7F6F);
|
||||
|
||||
/************************* Isochronous Byte Counts *************************/
|
||||
SFRX(OUT8BCH, 0x7F70);
|
||||
SFRX(OUT8BCL, 0x7F71);
|
||||
SFRX(OUT9BCH, 0x7F72);
|
||||
SFRX(OUT9BCL, 0x7F73);
|
||||
SFRX(OUT10BCH, 0x7F74);
|
||||
SFRX(OUT10BCL, 0x7F75);
|
||||
SFRX(OUT11BCH, 0x7F76);
|
||||
SFRX(OUT11BCL, 0x7F77);
|
||||
SFRX(OUT12BCH, 0x7F78);
|
||||
SFRX(OUT12BCL, 0x7F79);
|
||||
SFRX(OUT13BCH, 0x7F7A);
|
||||
SFRX(OUT13BCL, 0x7F7B);
|
||||
SFRX(OUT14BCH, 0x7F7C);
|
||||
SFRX(OUT14BCL, 0x7F7D);
|
||||
SFRX(OUT15BCH, 0x7F7E);
|
||||
SFRX(OUT16BCL, 0x7F7F);
|
||||
|
||||
/****************************** CPU Registers ******************************/
|
||||
SFRX(CPUCS, 0x7F92);
|
||||
#define RES8051 bmBit0
|
||||
#define CLK24OE bmBit1
|
||||
// Bit 2 read-only, always reads '0'
|
||||
// Bit 3 read-only, always reads '0'
|
||||
// Bits 4...7: Chip Revision
|
||||
|
||||
SFRX(PORTACFG, 0x7F93);
|
||||
#define T0OUT bmBit0
|
||||
#define T1OUT bmBit1
|
||||
#define OE bmBit2
|
||||
#define CS bmBit3
|
||||
#define FWR bmBit4
|
||||
#define FRD bmBit5
|
||||
#define RXD0OUT bmBit6
|
||||
#define RXD1OUT bmBit7
|
||||
|
||||
SFRX(PORTBCFG, 0x7F94);
|
||||
#define T2 bmBit0
|
||||
#define T2EX bmBit1
|
||||
#define RXD1 bmBit2
|
||||
#define TXD1 bmBit3
|
||||
#define INT4 bmBit4
|
||||
#define INT5 bmBit5
|
||||
#define INT6 bmBit6
|
||||
#define T2OUT bmBit7
|
||||
|
||||
SFRX(PORTCCFG, 0x7F95);
|
||||
#define RXD0 bmBit0
|
||||
#define TXD0 bmBit1
|
||||
#define INT0 bmBit2
|
||||
#define INT1 bmBit3
|
||||
#define T0 bmBit4
|
||||
#define T1 bmBit5
|
||||
#define WR bmBit6
|
||||
#define RD bmBit7
|
||||
|
||||
/*********************** Input-Output Port Registers ***********************/
|
||||
SFRX(OUTA, 0x7F96);
|
||||
#define OUTA0 bmBit0
|
||||
#define OUTA1 bmBit1
|
||||
#define OUTA2 bmBit2
|
||||
#define OUTA3 bmBit3
|
||||
#define OUTA4 bmBit4
|
||||
#define OUTA5 bmBit5
|
||||
#define OUTA6 bmBit6
|
||||
#define OUTA7 bmBit7
|
||||
|
||||
SFRX(OUTB, 0x7F97);
|
||||
#define OUTB0 bmBit0
|
||||
#define OUTB1 bmBit1
|
||||
#define OUTB2 bmBit2
|
||||
#define OUTB3 bmBit3
|
||||
#define OUTB4 bmBit4
|
||||
#define OUTB5 bmBit5
|
||||
#define OUTB6 bmBit6
|
||||
#define OUTB7 bmBit7
|
||||
|
||||
SFRX(OUTC, 0x7F98);
|
||||
#define OUTC0 bmBit0
|
||||
#define OUTC1 bmBit1
|
||||
#define OUTC2 bmBit2
|
||||
#define OUTC3 bmBit3
|
||||
#define OUTC4 bmBit4
|
||||
#define OUTC5 bmBit5
|
||||
#define OUTC6 bmBit6
|
||||
#define OUTC7 bmBit7
|
||||
|
||||
SFRX(PINSA, 0x7F99);
|
||||
#define PINA0 bmBit0
|
||||
#define PINA1 bmBit1
|
||||
#define PINA2 bmBit2
|
||||
#define PINA3 bmBit3
|
||||
#define PINA4 bmBit4
|
||||
#define PINA5 bmBit5
|
||||
#define PINA6 bmBit6
|
||||
#define PINA7 bmBit7
|
||||
|
||||
SFRX(PINSB, 0x7F9A);
|
||||
#define PINB0 bmBit0
|
||||
#define PINB1 bmBit1
|
||||
#define PINB2 bmBit2
|
||||
#define PINB3 bmBit3
|
||||
#define PINB4 bmBit4
|
||||
#define PINB5 bmBit5
|
||||
#define PINB6 bmBit6
|
||||
#define PINB7 bmBit7
|
||||
|
||||
SFRX(PINSC, 0x7F9B);
|
||||
#define PINC0 bmBit0
|
||||
#define PINC1 bmBit1
|
||||
#define PINC2 bmBit2
|
||||
#define PINC3 bmBit3
|
||||
#define PINC4 bmBit4
|
||||
#define PINC5 bmBit5
|
||||
#define PINC6 bmBit6
|
||||
#define PINC7 bmBit7
|
||||
|
||||
SFRX(OEA, 0x7F9C);
|
||||
#define OEA0 bmBit0
|
||||
#define OEA1 bmBit1
|
||||
#define OEA2 bmBit2
|
||||
#define OEA3 bmBit3
|
||||
#define OEA4 bmBit4
|
||||
#define OEA5 bmBit5
|
||||
#define OEA6 bmBit6
|
||||
#define OEA7 bmBit7
|
||||
|
||||
SFRX(OEB, 0x7F9D);
|
||||
#define OEB0 bmBit0
|
||||
#define OEB1 bmBit1
|
||||
#define OEB2 bmBit2
|
||||
#define OEB3 bmBit3
|
||||
#define OEB4 bmBit4
|
||||
#define OEB5 bmBit5
|
||||
#define OEB6 bmBit6
|
||||
#define OEB7 bmBit7
|
||||
|
||||
SFRX(OEC, 0x7F9E);
|
||||
#define OEC0 bmBit0
|
||||
#define OEC1 bmBit1
|
||||
#define OEC2 bmBit2
|
||||
#define OEC3 bmBit3
|
||||
#define OEC4 bmBit4
|
||||
#define OEC5 bmBit5
|
||||
#define OEC6 bmBit6
|
||||
#define OEC7 bmBit7
|
||||
|
||||
// 0x7F9F reserved
|
||||
|
||||
/****************** Isochronous Control/Status Registers *******************/
|
||||
SFRX(ISOERR, 0x7FA0);
|
||||
#define ISO8ERR bmBit0
|
||||
#define ISO9ERR bmBit1
|
||||
#define ISO10ERR bmBit2
|
||||
#define ISO11ERR bmBit3
|
||||
#define ISO12ERR bmBit4
|
||||
#define ISO13ERR bmBit5
|
||||
#define ISO14ERR bmBit6
|
||||
#define ISO15ERR bmBit7
|
||||
|
||||
SFRX(ISOCTL, 0x7FA1);
|
||||
#define ISODISAB bmBit0
|
||||
#define MBZ0 bmBit1
|
||||
#define MBZ1 bmBit2
|
||||
#define PPSTAT bmBit3
|
||||
// Bit 4 unused
|
||||
// Bit 5 unused
|
||||
// Bit 6 unused
|
||||
// Bit 7 unused
|
||||
|
||||
SFRX(ZBCOUT, 0x7FA2);
|
||||
#define EP8 bmBit0
|
||||
#define EP9 bmBit1
|
||||
#define EP10 bmBit2
|
||||
#define EP11 bmBit3
|
||||
#define EP12 bmBit4
|
||||
#define EP13 bmBit5
|
||||
#define EP14 bmBit6
|
||||
#define EP15 bmBit7
|
||||
|
||||
// 0x7FA3 reserved
|
||||
// 0x7FA4 reserved
|
||||
|
||||
/****************************** I2C Registers ******************************/
|
||||
SFRX(I2CS, 0x7FA5);
|
||||
#define DONE bmBit0
|
||||
#define ACK bmBit1
|
||||
#define BERR bmBit2
|
||||
#define ID0 bmBit3
|
||||
#define ID1 bmBit4
|
||||
#define LASTRD bmBit5
|
||||
#define I2C_STOP bmBit6
|
||||
#define I2C_START bmBit7
|
||||
|
||||
SFRX(I2DAT, 0x7FA6);
|
||||
// 0x7FA7 reserved
|
||||
|
||||
/******************************* Interrupts ********************************/
|
||||
SFRX(IVEC, 0x7FA8);
|
||||
// Bit 0 read-only, always reads '0'
|
||||
// Bit 1 read-only, always reads '0'
|
||||
#define IV0 bmBit2
|
||||
#define IV1 bmBit3
|
||||
#define IV2 bmBit4
|
||||
#define IV3 bmBit5
|
||||
#define IV4 bmBit6
|
||||
// Bit 7 read-only, always reads '0'
|
||||
|
||||
SFRX(IN07IRQ, 0x7FA9);
|
||||
#define IN0IR bmBit0
|
||||
#define IN1IR bmBit1
|
||||
#define IN2IR bmBit2
|
||||
#define IN3IR bmBit3
|
||||
#define IN4IR bmBit4
|
||||
#define IN5IR bmBit5
|
||||
#define IN6IR bmBit6
|
||||
#define IN7IR bmBit7
|
||||
|
||||
SFRX(OUT07IRQ, 0x7FAA);
|
||||
#define OUT0IR bmBit0
|
||||
#define OUT1IR bmBit1
|
||||
#define OUT2IR bmBit2
|
||||
#define OUT3IR bmBit3
|
||||
#define OUT4IR bmBit4
|
||||
#define OUT5IR bmBit5
|
||||
#define OUT6IR bmBit6
|
||||
#define OUT7IR bmBit7
|
||||
|
||||
SFRX(USBIRQ, 0x7FAB);
|
||||
#define SUDAVIR bmBit0
|
||||
#define SOFIR bmBit1
|
||||
#define SUTOKIR bmBit2
|
||||
#define SUSPIR bmBit3
|
||||
#define URESIR bmBit4
|
||||
// Bit 5 unused
|
||||
// Bit 6 unused
|
||||
// Bit 7 unused
|
||||
|
||||
SFRX(IN07IEN, 0x7FAC);
|
||||
#define IN0IEN bmBit0
|
||||
#define IN1IEN bmBit1
|
||||
#define IN2IEN bmBit2
|
||||
#define IN3IEN bmBit3
|
||||
#define IN4IEN bmBit4
|
||||
#define IN5IEN bmBit5
|
||||
#define IN6IEN bmBit6
|
||||
#define IN7IEN bmBit7
|
||||
|
||||
SFRX(OUT07IEN, 0x7FAD);
|
||||
#define OUT0IEN bmBit0
|
||||
#define OUT1IEN bmBit1
|
||||
#define OUT2IEN bmBit2
|
||||
#define OUT3IEN bmBit3
|
||||
#define OUT4IEN bmBit4
|
||||
#define OUT5IEN bmBit5
|
||||
#define OUT6IEN bmBit6
|
||||
#define OUT7IEN bmBit7
|
||||
|
||||
SFRX(USBIEN, 0x7FAE);
|
||||
#define SUDAVIE bmBit0
|
||||
#define SOFIE bmBit1
|
||||
#define SUTOKIE bmBit2
|
||||
#define SUSPIE bmBit3
|
||||
#define URESIE bmBit4
|
||||
// Bit 5 unused
|
||||
// Bit 6 unused
|
||||
// Bit 7 unused
|
||||
|
||||
SFRX(USBBAV, 0x7FAF);
|
||||
#define AVEN bmBit0
|
||||
#define BPEN bmBit1
|
||||
#define BPPULSE bmBit2
|
||||
#define BREAK bmBit3
|
||||
// Bit 4 unused
|
||||
// Bit 5 unused
|
||||
// Bit 6 unused
|
||||
// Bit 7 unused
|
||||
|
||||
// 0x7FB0 reserved
|
||||
// 0x7FB1 reserved
|
||||
SFRX(BPADDRH, 0x7FB2);
|
||||
SFRX(BPADDRL, 0x7FB3);
|
||||
|
||||
/****************************** Endpoints 0-7 ******************************/
|
||||
SFRX(EP0CS, 0x7FB4);
|
||||
#define EP0STALL bmBit0
|
||||
#define HSNAK bmBit1
|
||||
#define IN0BSY bmBit2
|
||||
#define OUT0BSY bmBit3
|
||||
// Bit 4 unused
|
||||
// Bit 5 unused
|
||||
// Bit 6 unused
|
||||
// Bit 7 unused
|
||||
|
||||
SFRX(IN0BC, 0x7FB5);
|
||||
SFRX(IN1CS, 0x7FB6);
|
||||
SFRX(IN1BC, 0x7FB7);
|
||||
SFRX(IN2CS, 0x7FB8);
|
||||
SFRX(IN2BC, 0x7FB9);
|
||||
SFRX(IN3CS, 0x7FBA);
|
||||
SFRX(IN3BC, 0x7FBB);
|
||||
SFRX(IN4CS, 0x7FBC);
|
||||
SFRX(IN4BC, 0x7FBD);
|
||||
SFRX(IN5CS, 0x7FBE);
|
||||
SFRX(IN5BC, 0x7FBF);
|
||||
SFRX(IN6CS, 0x7FC0);
|
||||
SFRX(IN6BC, 0x7FC1);
|
||||
SFRX(IN7CS, 0x7FC2);
|
||||
SFRX(IN7BC, 0x7FC3);
|
||||
// 0x7FC4 reserved
|
||||
SFRX(OUT0BC, 0x7FC5);
|
||||
SFRX(OUT1CS, 0x7FC6);
|
||||
SFRX(OUT1BC, 0x7FC7);
|
||||
SFRX(OUT2CS, 0x7FC8);
|
||||
SFRX(OUT2BC, 0x7FC9);
|
||||
SFRX(OUT3CS, 0x7FCA);
|
||||
SFRX(OUT3BC, 0x7FCB);
|
||||
SFRX(OUT4CS, 0x7FCC);
|
||||
SFRX(OUT4BC, 0x7FCD);
|
||||
SFRX(OUT5CS, 0x7FCE);
|
||||
SFRX(OUT5BC, 0x7FCF);
|
||||
SFRX(OUT6CS, 0x7FD0);
|
||||
SFRX(OUT6BC, 0x7FD1);
|
||||
SFRX(OUT7CS, 0x7FD2);
|
||||
SFRX(OUT7BC, 0x7FD3);
|
||||
|
||||
/* The INxSTALL, OUTxSTALL, INxBSY and OUTxBSY bits are the same for all
|
||||
* INxCS/OUTxCS registers. For better readability, we define them only once */
|
||||
#define EPSTALL bmBit0
|
||||
#define EPBSY bmBit1
|
||||
|
||||
/************************** Global USB Registers ***************************/
|
||||
SFRX(SUDPTRH, 0x7FD4);
|
||||
SFRX(SUDPTRL, 0x7FD5);
|
||||
|
||||
SFRX(USBCS, 0x7FD6);
|
||||
#define SIGRSUME bmBit0
|
||||
#define RENUM bmBit1
|
||||
#define DISCOE bmBit2
|
||||
#define DISCON bmBit3
|
||||
// Bit 4 unused
|
||||
// Bit 5 unused
|
||||
// Bit 6 unused
|
||||
#define WAKESRC bmBit7
|
||||
|
||||
SFRX(TOGCTL, 0x7FD7);
|
||||
#define TOG_EP0 bmBit0
|
||||
#define TOG_EP1 bmBit1
|
||||
#define TOG_EP2 bmBit2
|
||||
// Bit 3 is read-only, always reads '0'
|
||||
#define TOG_IO bmBit4
|
||||
#define TOG_R bmBit5
|
||||
#define TOG_S bmBit6
|
||||
#define TOG_Q bmBit7
|
||||
|
||||
SFRX(USBFRAMEL, 0x7FD8);
|
||||
SFRX(USBFRAMEH, 0x7FD9);
|
||||
// 0x7FDA reserved
|
||||
SFRX(FNADDR, 0x7FDB);
|
||||
// 0x7FDC reserved
|
||||
|
||||
SFRX(USBPAIR, 0x7FDD);
|
||||
#define PR2IN bmBit0
|
||||
#define PR4IN bmBit1
|
||||
#define PR6IN bmBit2
|
||||
#define PR2OUT bmBit3
|
||||
#define PR4OUT bmBit4
|
||||
#define PR6OUT bmBit5
|
||||
// Bit 6 unused
|
||||
#define ISOSEND0 bmBit7
|
||||
|
||||
SFRX(IN07VAL, 0x7FDE);
|
||||
// Bit 0 is read-only, always reads '1'
|
||||
#define IN1VAL bmBit1
|
||||
#define IN2VAL bmBit2
|
||||
#define IN3VAL bmBit3
|
||||
#define IN4VAL bmBit4
|
||||
#define IN5VAL bmBit5
|
||||
#define IN6VAL bmBit6
|
||||
#define IN7VAL bmBit7
|
||||
|
||||
SFRX(OUT07VAL, 0x7FDF);
|
||||
// Bit 0 is read-only, always reads '1'
|
||||
#define OUT1VAL bmBit1
|
||||
#define OUT2VAL bmBit2
|
||||
#define OUT3VAL bmBit3
|
||||
#define OUT4VAL bmBit4
|
||||
#define OUT5VAL bmBit5
|
||||
#define OUT6VAL bmBit6
|
||||
#define OUT7VAL bmBit7
|
||||
|
||||
SFRX(INISOVAL, 0x7FE0);
|
||||
#define IN8VAL bmBit0
|
||||
#define IN9VAL bmBit1
|
||||
#define IN10VAL bmBit2
|
||||
#define IN11VAL bmBit3
|
||||
#define IN12VAL bmBit4
|
||||
#define IN13VAL bmBit5
|
||||
#define IN14VAL bmBit6
|
||||
#define IN15VAL bmBit7
|
||||
|
||||
SFRX(OUTISOVAL, 0x7FE1);
|
||||
#define OUT8VAL bmBit0
|
||||
#define OUT9VAL bmBit1
|
||||
#define OUT10VAL bmBit2
|
||||
#define OUT11VAL bmBit3
|
||||
#define OUT12VAL bmBit4
|
||||
#define OUT13VAL bmBit5
|
||||
#define OUT14VAL bmBit6
|
||||
#define OUT15VAL bmBit7
|
||||
|
||||
SFRX(FASTXFR, 0x7FE2);
|
||||
#define WMOD0 bmBit0
|
||||
#define WMOD1 bmBit1
|
||||
#define WPOL bmBit2
|
||||
#define RMOD0 bmBit3
|
||||
#define RMOD1 bmBit4
|
||||
#define RPOL bmBit5
|
||||
#define FBLK bmBit6
|
||||
#define FISO bmBit7
|
||||
|
||||
SFRX(AUTOPTRH, 0x7FE3);
|
||||
SFRX(AUTOPTRL, 0x7FE4);
|
||||
SFRX(AUTODATA, 0x7FE5);
|
||||
// 0x7FE6 reserved
|
||||
// 0x7FE7 reserved
|
||||
|
||||
/******************************* Setup Data ********************************/
|
||||
SFRX(SETUPDAT[8], 0x7FE8);
|
||||
|
||||
/************************* Isochronous FIFO sizes **************************/
|
||||
SFRX(OUT8ADDR, 0x7FF0);
|
||||
SFRX(OUT9ADDR, 0x7FF1);
|
||||
SFRX(OUT10ADDR, 0x7FF2);
|
||||
SFRX(OUT11ADDR, 0x7FF3);
|
||||
SFRX(OUT12ADDR, 0x7FF4);
|
||||
SFRX(OUT13ADDR, 0x7FF5);
|
||||
SFRX(OUT14ADDR, 0x7FF6);
|
||||
SFRX(OUT15ADDR, 0x7FF7);
|
||||
|
||||
SFRX(IN8ADDR, 0x7FF8);
|
||||
SFRX(IN9ADDR, 0x7FF9);
|
||||
SFRX(IN10ADDR, 0x7FFA);
|
||||
SFRX(IN11ADDR, 0x7FFB);
|
||||
SFRX(IN12ADDR, 0x7FFC);
|
||||
SFRX(IN13ADDR, 0x7FFD);
|
||||
SFRX(IN14ADDR, 0x7FFE);
|
||||
SFRX(IN15ADDR, 0x7FFF);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,41 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Martin Schmoelzer *
|
||||
* <martin.schmoelzer@student.tuwien.ac.at> *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __SHORTTYPES_H
|
||||
#define __SHORTTYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @file Integer type definitions for shorter code (easier to stay within 80
|
||||
* character maximum line length).
|
||||
*/
|
||||
|
||||
/* Signed integers */
|
||||
typedef int8_t s8;
|
||||
typedef int16_t s16;
|
||||
typedef int32_t s32;
|
||||
|
||||
/* Unsigned integers */
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,267 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Martin Schmoelzer *
|
||||
* <martin.schmoelzer@student.tuwien.ac.at> *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __USB_H
|
||||
#define __USB_H
|
||||
|
||||
#include "shorttypes.h"
|
||||
#include "reg_ezusb.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define NULL (void*)0;
|
||||
|
||||
/* High and Low byte of a word (u16) */
|
||||
#define HI8(word) (u8)(((u16)word >> 8) & 0xff)
|
||||
#define LO8(word) (u8)((u16)word & 0xff)
|
||||
|
||||
/* Convenience functions */
|
||||
#define STALL_EP0() EP0CS |= EP0STALL
|
||||
#define CLEAR_IRQ() EXIF &= ~USBINT
|
||||
|
||||
/*********** USB descriptors. See section 9.5 of the USB 1.1 spec **********/
|
||||
|
||||
/* USB Descriptor Types. See USB 1.1 spec, page 187, table 9-5 */
|
||||
#define DESCRIPTOR_TYPE_DEVICE 0x01
|
||||
#define DESCRIPTOR_TYPE_CONFIGURATION 0x02
|
||||
#define DESCRIPTOR_TYPE_STRING 0x03
|
||||
#define DESCRIPTOR_TYPE_INTERFACE 0x04
|
||||
#define DESCRIPTOR_TYPE_ENDPOINT 0x05
|
||||
|
||||
#define STR_DESCR(len,...) { len*2+2, DESCRIPTOR_TYPE_STRING, { __VA_ARGS__ } }
|
||||
|
||||
/** USB Device Descriptor. See USB 1.1 spec, pp. 196 - 198 */
|
||||
typedef struct {
|
||||
u8 bLength; ///< Size of this descriptor in bytes.
|
||||
u8 bDescriptorType; ///< DEVICE Descriptor Type.
|
||||
u16 bcdUSB; ///< USB specification release number (BCD).
|
||||
u8 bDeviceClass; ///< Class code.
|
||||
u8 bDeviceSubClass; ///< Subclass code.
|
||||
u8 bDeviceProtocol; ///< Protocol code.
|
||||
u8 bMaxPacketSize0; ///< Maximum packet size for EP0 (8, 16, 32, 64).
|
||||
u16 idVendor; ///< USB Vendor ID.
|
||||
u16 idProduct; ///< USB Product ID.
|
||||
u16 bcdDevice; ///< Device Release Number (BCD).
|
||||
u8 iManufacturer; ///< Index of manufacturer string descriptor.
|
||||
u8 iProduct; ///< Index of product string descriptor.
|
||||
u8 iSerialNumber; ///< Index of string descriptor containing serial #.
|
||||
u8 bNumConfigurations; ///< Number of possible configurations.
|
||||
} usb_device_descriptor_t;
|
||||
|
||||
/** USB Configuration Descriptor. See USB 1.1 spec, pp. 199 - 200 */
|
||||
typedef struct {
|
||||
u8 bLength; ///< Size of this descriptor in bytes.
|
||||
u8 bDescriptorType; ///< CONFIGURATION descriptor type.
|
||||
u16 wTotalLength; ///< Combined total length of all descriptors.
|
||||
u8 bNumInterfaces; ///< Number of interfaces in this configuration.
|
||||
u8 bConfigurationValue; ///< Value used to select this configuration.
|
||||
u8 iConfiguration; ///< Index of configuration string descriptor.
|
||||
u8 bmAttributes; ///< Configuration characteristics.
|
||||
u8 MaxPower; ///< Maximum power consumption in 2 mA units.
|
||||
} usb_config_descriptor_t;
|
||||
|
||||
/** USB Interface Descriptor. See USB 1.1 spec, pp. 201 - 203 */
|
||||
typedef struct {
|
||||
u8 bLength; ///< Size of this descriptor in bytes.
|
||||
u8 bDescriptorType; ///< INTERFACE descriptor type.
|
||||
u8 bInterfaceNumber; ///< Interface number.
|
||||
u8 bAlternateSetting; ///< Value used to select alternate setting.
|
||||
u8 bNumEndpoints; ///< Number of endpoints used by this interface.
|
||||
u8 bInterfaceClass; ///< Class code.
|
||||
u8 bInterfaceSubclass; ///< Subclass code.
|
||||
u8 bInterfaceProtocol; ///< Protocol code.
|
||||
u8 iInterface; ///< Index of interface string descriptor.
|
||||
} usb_interface_descriptor_t;
|
||||
|
||||
/** USB Endpoint Descriptor. See USB 1.1 spec, pp. 203 - 204 */
|
||||
typedef struct {
|
||||
u8 bLength; ///< Size of this descriptor in bytes.
|
||||
u8 bDescriptorType; ///< ENDPOINT descriptor type.
|
||||
u8 bEndpointAddress; ///< Endpoint Address: USB 1.1 spec, table 9-10.
|
||||
u8 bmAttributes; ///< Endpoint Attributes: USB 1.1 spec, table 9-10.
|
||||
u16 wMaxPacketSize; ///< Maximum packet size for this endpoint.
|
||||
u8 bInterval; ///< Polling interval (in ms) for this endpoint.
|
||||
} usb_endpoint_descriptor_t;
|
||||
|
||||
/** USB Language Descriptor. See USB 1.1 spec, pp. 204 - 205 */
|
||||
typedef struct {
|
||||
u8 bLength; ///< Size of this descriptor in bytes.
|
||||
u8 bDescriptorType; ///< STRING descriptor type.
|
||||
u16 wLANGID[]; ///< LANGID codes.
|
||||
} usb_language_descriptor_t;
|
||||
|
||||
/** USB String Descriptor. See USB 1.1 spec, pp. 204 - 205 */
|
||||
typedef struct {
|
||||
u8 bLength; ///< Size of this descriptor in bytes.
|
||||
u8 bDescriptorType; ///< STRING descriptor type.
|
||||
u16 bString[]; ///< UNICODE encoded string.
|
||||
} usb_string_descriptor_t;
|
||||
|
||||
/********************** USB Control Endpoint 0 related *********************/
|
||||
|
||||
/** USB Control Setup Data. See USB 1.1 spec, pp. 183 - 185 */
|
||||
typedef struct {
|
||||
u8 bmRequestType; ///< Characteristics of a request.
|
||||
u8 bRequest; ///< Specific request.
|
||||
u16 wValue; ///< Field that varies according to request.
|
||||
u16 wIndex; ///< Field that varies according to request.
|
||||
u16 wLength; ///< Number of bytes to transfer in data stage.
|
||||
} setup_data_t;
|
||||
|
||||
/* External declarations for variables that need to be accessed outside of
|
||||
* the USB module */
|
||||
extern volatile bool EP2_out;
|
||||
extern volatile bool EP2_in;
|
||||
extern volatile __xdata __at 0x7FE8 setup_data_t setup_data;
|
||||
|
||||
/*
|
||||
* USB Request Types (bmRequestType): See USB 1.1 spec, page 183, table 9-2
|
||||
*
|
||||
* Bit 7: Data transfer direction
|
||||
* 0 = Host-to-device
|
||||
* 1 = Device-to-host
|
||||
* Bit 6...5: Type
|
||||
* 0 = Standard
|
||||
* 1 = Class
|
||||
* 2 = Vendor
|
||||
* 3 = Reserved
|
||||
* Bit 4...0: Recipient
|
||||
* 0 = Device
|
||||
* 1 = Interface
|
||||
* 2 = Endpoint
|
||||
* 3 = Other
|
||||
* 4...31 = Reserved
|
||||
*/
|
||||
|
||||
#define USB_DIR_OUT 0x00
|
||||
#define USB_DIR_IN 0x80
|
||||
|
||||
#define USB_REQ_TYPE_STANDARD (0x00 << 5)
|
||||
#define USB_REQ_TYPE_CLASS (0x01 << 5)
|
||||
#define USB_REQ_TYPE_VENDOR (0x02 << 5)
|
||||
#define USB_REQ_TYPE_RESERVED (0x03 << 5)
|
||||
|
||||
#define USB_RECIP_DEVICE 0x00
|
||||
#define USB_RECIP_INTERFACE 0x01
|
||||
#define USB_RECIP_ENDPOINT 0x02
|
||||
#define USB_RECIP_OTHER 0x03
|
||||
|
||||
/* bmRequestType for USB Standard Requests */
|
||||
|
||||
/* Clear Interface Request */
|
||||
#define CF_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
|
||||
#define CF_INTERFACE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)
|
||||
#define CF_ENDPOINT (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT)
|
||||
|
||||
/* Get Configuration Request */
|
||||
#define GC_DEVICE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
|
||||
|
||||
/* Get Descriptor Request */
|
||||
#define GD_DEVICE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
|
||||
|
||||
/* Get Interface Request */
|
||||
#define GI_INTERFACE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)
|
||||
|
||||
/* Get Status Request: See USB 1.1 spec, page 190 */
|
||||
#define GS_DEVICE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
|
||||
#define GS_INTERFACE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)
|
||||
#define GS_ENDPOINT (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT)
|
||||
|
||||
/* Set Address Request is handled by EZ-USB core */
|
||||
|
||||
/* Set Configuration Request */
|
||||
#define SC_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
|
||||
|
||||
/* Set Descriptor Request */
|
||||
#define SD_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
|
||||
|
||||
/* Set Feature Request */
|
||||
#define SF_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
|
||||
#define SF_INTERFACE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)
|
||||
#define SF_ENDPOINT (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT)
|
||||
|
||||
/* Set Interface Request */
|
||||
#define SI_INTERFACE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)
|
||||
|
||||
/* Synch Frame Request */
|
||||
#define SY_ENDPOINT (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT)
|
||||
|
||||
/* USB Requests (bRequest): See USB 1.1 spec, table 9-4 on page 187 */
|
||||
#define GET_STATUS 0
|
||||
#define CLEAR_FEATURE 1
|
||||
// Value '2' is reserved for future use
|
||||
#define SET_FEATURE 3
|
||||
// Value '4' is reserved for future use
|
||||
#define SET_ADDRESS 5
|
||||
#define GET_DESCRIPTOR 6
|
||||
#define SET_DESCRIPTOR 7
|
||||
#define GET_CONFIGURATION 8
|
||||
#define SET_CONFIGURATION 9
|
||||
#define GET_INTERFACE 10
|
||||
#define SET_INTERFACE 11
|
||||
#define SYNCH_FRAME 12
|
||||
|
||||
/* Standard Feature Selectors: See USB 1.1 spec, table 9-6 on page 188 */
|
||||
#define DEVICE_REMOTE_WAKEUP 1
|
||||
#define ENDPOINT_HALT 0
|
||||
|
||||
/************************** EZ-USB specific stuff **************************/
|
||||
|
||||
/** USB Interrupts. See AN2131-TRM, page 9-4 for details */
|
||||
typedef enum {
|
||||
SUDAV_ISR = 13,
|
||||
SOF_ISR,
|
||||
SUTOK_ISR,
|
||||
SUSPEND_ISR,
|
||||
USBRESET_ISR,
|
||||
IBN_ISR,
|
||||
EP0IN_ISR,
|
||||
EP0OUT_ISR,
|
||||
EP1IN_ISR,
|
||||
EP1OUT_ISR,
|
||||
EP2IN_ISR,
|
||||
EP2OUT_ISR,
|
||||
EP3IN_ISR,
|
||||
EP3OUT_ISR,
|
||||
EP4IN_ISR,
|
||||
EP4OUT_ISR,
|
||||
EP5IN_ISR,
|
||||
EP5OUT_ISR,
|
||||
EP6IN_ISR,
|
||||
EP6OUT_ISR,
|
||||
EP7IN_ISR,
|
||||
EP7OUT_ISR
|
||||
} USB_ISR;
|
||||
|
||||
/*************************** Function Prototypes ***************************/
|
||||
|
||||
__xdata u8* usb_get_endpoint_cs_reg(u8 ep);
|
||||
void usb_reset_data_toggle(u8 ep);
|
||||
|
||||
bool usb_handle_get_status(void);
|
||||
bool usb_handle_clear_feature(void);
|
||||
bool usb_handle_set_feature(void);
|
||||
bool usb_handle_get_descriptor(void);
|
||||
void usb_handle_set_interface(void);
|
||||
|
||||
void usb_handle_setup_data(void);
|
||||
void usb_init(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,83 @@
|
|||
;--------------------------------------------------------------------------;
|
||||
; Copyright (C) 2011 by Martin Schmoelzer ;
|
||||
; <martin.schmoelzer@student.tuwien.ac.at> ;
|
||||
; ;
|
||||
; 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. ;
|
||||
;--------------------------------------------------------------------------;
|
||||
|
||||
.module JUMPTABLE
|
||||
.globl USB_AutoVector
|
||||
.globl USB_Jump_Table
|
||||
|
||||
;--------------------------------------------------------------------------;
|
||||
; Interrupt Vectors ;
|
||||
;--------------------------------------------------------------------------;
|
||||
.area USB_JV (ABS,OVR) ; Absolute, Overlay
|
||||
.org 0x43 ; USB interrupt (INT2) jumps here
|
||||
USB_AutoVector = #. + 2
|
||||
ljmp USB_jump_table
|
||||
|
||||
;--------------------------------------------------------------------------;
|
||||
; USB Jump Table ;
|
||||
;--------------------------------------------------------------------------;
|
||||
.area USB_JT (ABS) ; Absolute placement
|
||||
.org 0x1B00 ; Place jump table at 0x1B00
|
||||
|
||||
USB_jump_table: ; autovector jump table
|
||||
ljmp _sudav_isr ; Setup Data Available
|
||||
.db 0
|
||||
ljmp _sof_isr ; Start of Frame
|
||||
.db 0
|
||||
ljmp _sutok_isr ; Setup Data Loading
|
||||
.db 0
|
||||
ljmp _suspend_isr ; Global Suspend
|
||||
.db 0
|
||||
ljmp _usbreset_isr ; USB Reset
|
||||
.db 0
|
||||
ljmp _ibn_isr ; IN Bulk NAK interrupt
|
||||
.db 0
|
||||
ljmp _ep0in_isr ; Endpoint 0 IN
|
||||
.db 0
|
||||
ljmp _ep0out_isr ; Endpoint 0 OUT
|
||||
.db 0
|
||||
ljmp _ep1in_isr ; Endpoint 1 IN
|
||||
.db 0
|
||||
ljmp _ep1out_isr ; Endpoint 1 OUT
|
||||
.db 0
|
||||
ljmp _ep2in_isr ; Endpoint 2 IN
|
||||
.db 0
|
||||
ljmp _ep2out_isr ; Endpoint 2 OUT
|
||||
.db 0
|
||||
ljmp _ep3in_isr ; Endpoint 3 IN
|
||||
.db 0
|
||||
ljmp _ep3out_isr ; Endpoint 3 OUT
|
||||
.db 0
|
||||
ljmp _ep4in_isr ; Endpoint 4 IN
|
||||
.db 0
|
||||
ljmp _ep4out_isr ; Endpoint 4 OUT
|
||||
.db 0
|
||||
ljmp _ep5in_isr ; Endpoint 5 IN
|
||||
.db 0
|
||||
ljmp _ep5out_isr ; Endpoint 5 OUT
|
||||
.db 0
|
||||
ljmp _ep6in_isr ; Endpoint 6 IN
|
||||
.db 0
|
||||
ljmp _ep6out_isr ; Endpoint 6 OUT
|
||||
.db 0
|
||||
ljmp _ep7in_isr ; Endpoint 7 IN
|
||||
.db 0
|
||||
ljmp _ep7out_isr ; Endpoint 7 OUT
|
||||
.db 0
|
|
@ -0,0 +1,51 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Martin Schmoelzer *
|
||||
* <martin.schmoelzer@student.tuwien.ac.at> *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#include "delay.h"
|
||||
|
||||
void delay_5us(void)
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
void delay_1ms(void) {
|
||||
u16 i;
|
||||
|
||||
for (i = 0; i < 598; i++);
|
||||
}
|
||||
|
||||
void delay_us(u16 delay)
|
||||
{
|
||||
u16 i;
|
||||
u16 maxcount = (delay / 5);
|
||||
|
||||
for (i = 0; i < maxcount; i++) {
|
||||
delay_5us();
|
||||
}
|
||||
}
|
||||
|
||||
void delay_ms(u16 delay)
|
||||
{
|
||||
u16 i;
|
||||
|
||||
for (i = 0; i < delay; i++) {
|
||||
delay_1ms();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,414 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Martin Schmoelzer *
|
||||
* <martin.schmoelzer@student.tuwien.ac.at> *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#include "jtag.h"
|
||||
|
||||
#include "io.h"
|
||||
#include "msgtypes.h"
|
||||
#include "common.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/** Delay value for SCAN operations with less than maximum TCK frequency */
|
||||
u8 delay_scan = 0;
|
||||
|
||||
/** Delay value for CLOCK_TCK operations */
|
||||
u8 delay_tck = 0;
|
||||
|
||||
/** Delay value for CLOCK_TMS operations with less than maximum frequency */
|
||||
u8 delay_tms = 0;
|
||||
|
||||
/**
|
||||
* Perform JTAG SCAN-IN operation at maximum TCK frequency.
|
||||
*
|
||||
* Dummy data is shifted into the JTAG chain via TDI, TDO data is sampled and
|
||||
* stored in the EP2 IN buffer.
|
||||
*
|
||||
* @param out_offset offset in OUT2BUF where payload data starts
|
||||
*/
|
||||
void jtag_scan_in(u8 out_offset, u8 in_offset)
|
||||
{
|
||||
u8 scan_size_bytes, bits_last_byte;
|
||||
u8 tms_count_start, tms_count_end;
|
||||
u8 tms_sequence_start, tms_sequence_end;
|
||||
u8 tdo_data, i, j;
|
||||
|
||||
u8 outb_buffer;
|
||||
|
||||
/* Get parameters from OUT2BUF */
|
||||
scan_size_bytes = OUT2BUF[out_offset];
|
||||
bits_last_byte = OUT2BUF[out_offset + 1];
|
||||
tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
|
||||
tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
|
||||
tms_sequence_start = OUT2BUF[out_offset + 3];
|
||||
tms_sequence_end = OUT2BUF[out_offset + 4];
|
||||
|
||||
if (tms_count_start > 0) {
|
||||
jtag_clock_tms(tms_count_start, tms_sequence_start);
|
||||
}
|
||||
|
||||
outb_buffer = OUTB & ~(PIN_TDI | PIN_TCK | PIN_TMS);
|
||||
|
||||
/* Shift all bytes except the last byte */
|
||||
for (i = 0; i < scan_size_bytes - 1; i++) {
|
||||
tdo_data = 0;
|
||||
|
||||
for (j = 0; j < 8; j++) {
|
||||
OUTB = outb_buffer; /* TCK changes here */
|
||||
OUTB = (outb_buffer | PIN_TCK);
|
||||
tdo_data = tdo_data >> 1;
|
||||
|
||||
if (GET_TDO()) {
|
||||
tdo_data |= 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy TDO data to IN2BUF */
|
||||
IN2BUF[i + in_offset] = tdo_data;
|
||||
}
|
||||
|
||||
tdo_data = 0;
|
||||
|
||||
/* Shift the last byte */
|
||||
for (j = 0; j < bits_last_byte; j++) {
|
||||
/* Assert TMS signal if requested and this is the last bit */
|
||||
if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
|
||||
outb_buffer |= PIN_TMS;
|
||||
tms_count_end--;
|
||||
tms_sequence_end = tms_sequence_end >> 1;
|
||||
}
|
||||
|
||||
OUTB = outb_buffer; /* TCK change here */
|
||||
OUTB = (outb_buffer | PIN_TCK);
|
||||
tdo_data = tdo_data >> 1;
|
||||
|
||||
if (GET_TDO()) {
|
||||
tdo_data |= 0x80;
|
||||
}
|
||||
}
|
||||
tdo_data = tdo_data >> (8 - bits_last_byte);
|
||||
|
||||
/* Copy TDO data to IN2BUF */
|
||||
IN2BUF[i + in_offset] = tdo_data;
|
||||
|
||||
/* Move to correct end state */
|
||||
if (tms_count_end > 0) {
|
||||
jtag_clock_tms(tms_count_end, tms_sequence_end);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform JTAG SCAN-OUT operation at maximum TCK frequency.
|
||||
*
|
||||
* Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
|
||||
* data is not sampled.
|
||||
* The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state.
|
||||
*
|
||||
* @param out_offset offset in OUT2BUF where payload data starts
|
||||
*/
|
||||
void jtag_scan_out(u8 out_offset)
|
||||
{
|
||||
u8 scan_size_bytes, bits_last_byte;
|
||||
u8 tms_count_start, tms_count_end;
|
||||
u8 tms_sequence_start, tms_sequence_end;
|
||||
u8 tdi_data, i, j;
|
||||
|
||||
u8 outb_buffer;
|
||||
|
||||
/* Get parameters from OUT2BUF */
|
||||
scan_size_bytes = OUT2BUF[out_offset];
|
||||
bits_last_byte = OUT2BUF[out_offset + 1];
|
||||
tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
|
||||
tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
|
||||
tms_sequence_start = OUT2BUF[out_offset + 3];
|
||||
tms_sequence_end = OUT2BUF[out_offset + 4];
|
||||
|
||||
if (tms_count_start > 0) {
|
||||
jtag_clock_tms(tms_count_start, tms_sequence_start);
|
||||
}
|
||||
|
||||
outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
|
||||
|
||||
/* Shift all bytes except the last byte */
|
||||
for (i = 0; i < scan_size_bytes - 1; i++) {
|
||||
tdi_data = OUT2BUF[i + out_offset + 5];
|
||||
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (tdi_data & 0x01) {
|
||||
outb_buffer |= PIN_TDI;
|
||||
}
|
||||
else {
|
||||
outb_buffer &= ~PIN_TDI;
|
||||
}
|
||||
|
||||
OUTB = outb_buffer; /* TDI and TCK change here */
|
||||
tdi_data = tdi_data >> 1;
|
||||
OUTB = (outb_buffer | PIN_TCK);
|
||||
}
|
||||
}
|
||||
|
||||
tdi_data = OUT2BUF[i + out_offset + 5];
|
||||
|
||||
/* Shift the last byte */
|
||||
for (j = 0; j < bits_last_byte; j++) {
|
||||
if (tdi_data & 0x01) {
|
||||
outb_buffer |= PIN_TDI;
|
||||
}
|
||||
else {
|
||||
outb_buffer &= ~PIN_TDI;
|
||||
}
|
||||
|
||||
/* Assert TMS signal if requested and this is the last bit */
|
||||
if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
|
||||
outb_buffer |= PIN_TMS;
|
||||
tms_count_end--;
|
||||
tms_sequence_end = tms_sequence_end >> 1;
|
||||
}
|
||||
|
||||
OUTB = outb_buffer; /* TDI and TCK change here */
|
||||
tdi_data = tdi_data >> 1;
|
||||
OUTB = (outb_buffer | PIN_TCK);
|
||||
}
|
||||
|
||||
/* Move to correct end state */
|
||||
if (tms_count_end > 0) {
|
||||
jtag_clock_tms(tms_count_end, tms_sequence_end);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform bidirectional JTAG SCAN operation at maximum TCK frequency.
|
||||
*
|
||||
* Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
|
||||
* data is sampled and stored in the EP2 IN buffer.
|
||||
* The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state.
|
||||
*
|
||||
* @param out_offset offset in OUT2BUF where payload data starts
|
||||
*/
|
||||
void jtag_scan_io(u8 out_offset, u8 in_offset)
|
||||
{
|
||||
u8 scan_size_bytes, bits_last_byte;
|
||||
u8 tms_count_start, tms_count_end;
|
||||
u8 tms_sequence_start, tms_sequence_end;
|
||||
u8 tdi_data, tdo_data, i, j;
|
||||
|
||||
u8 outb_buffer;
|
||||
|
||||
/* Get parameters from OUT2BUF */
|
||||
scan_size_bytes = OUT2BUF[out_offset];
|
||||
bits_last_byte = OUT2BUF[out_offset + 1];
|
||||
tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
|
||||
tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
|
||||
tms_sequence_start = OUT2BUF[out_offset + 3];
|
||||
tms_sequence_end = OUT2BUF[out_offset + 4];
|
||||
|
||||
if (tms_count_start > 0) {
|
||||
jtag_clock_tms(tms_count_start, tms_sequence_start);
|
||||
}
|
||||
|
||||
outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
|
||||
|
||||
/* Shift all bytes except the last byte */
|
||||
for (i = 0; i < scan_size_bytes - 1; i++) {
|
||||
tdi_data = OUT2BUF[i + out_offset + 5];
|
||||
tdo_data = 0;
|
||||
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (tdi_data & 0x01) {
|
||||
outb_buffer |= PIN_TDI;
|
||||
}
|
||||
else {
|
||||
outb_buffer &= ~PIN_TDI;
|
||||
}
|
||||
|
||||
OUTB = outb_buffer; /* TDI and TCK change here */
|
||||
tdi_data = tdi_data >> 1;
|
||||
OUTB = (outb_buffer | PIN_TCK);
|
||||
tdo_data = tdo_data >> 1;
|
||||
|
||||
if (GET_TDO()) {
|
||||
tdo_data |= 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy TDO data to IN2BUF */
|
||||
IN2BUF[i + in_offset] = tdo_data;
|
||||
}
|
||||
|
||||
tdi_data = OUT2BUF[i + out_offset + 5];
|
||||
tdo_data = 0;
|
||||
|
||||
/* Shift the last byte */
|
||||
for (j = 0; j < bits_last_byte; j++) {
|
||||
if (tdi_data & 0x01) {
|
||||
outb_buffer |= PIN_TDI;
|
||||
}
|
||||
else {
|
||||
outb_buffer &= ~PIN_TDI;
|
||||
}
|
||||
|
||||
/* Assert TMS signal if requested and this is the last bit */
|
||||
if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
|
||||
outb_buffer |= PIN_TMS;
|
||||
tms_count_end--;
|
||||
tms_sequence_end = tms_sequence_end >> 1;
|
||||
}
|
||||
|
||||
OUTB = outb_buffer; /* TDI and TCK change here */
|
||||
tdi_data = tdi_data >> 1;
|
||||
OUTB = (outb_buffer | PIN_TCK);
|
||||
tdo_data = tdo_data >> 1;
|
||||
|
||||
if (GET_TDO()) {
|
||||
tdo_data |= 0x80;
|
||||
}
|
||||
}
|
||||
tdo_data = tdo_data >> (8 - bits_last_byte);
|
||||
|
||||
/* Copy TDO data to IN2BUF */
|
||||
IN2BUF[i + in_offset] = tdo_data;
|
||||
|
||||
/* Move to correct end state */
|
||||
if (tms_count_end > 0) {
|
||||
jtag_clock_tms(tms_count_end, tms_sequence_end);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate TCK clock cycles.
|
||||
*
|
||||
* @param count number of TCK clock cyclces to generate.
|
||||
*/
|
||||
void jtag_clock_tck(u16 count)
|
||||
{
|
||||
u16 i;
|
||||
u8 j;
|
||||
|
||||
for ( i = 0; i < count; i++ ) {
|
||||
SET_TCK_LOW();
|
||||
for(j = 0; j < delay_tck; j++);
|
||||
|
||||
SET_TCK_HIGH();
|
||||
for(j = 0; j < delay_tck; j++);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform TAP-FSM state transitions at maximum TCK frequency.
|
||||
*
|
||||
* @param count the number of state transitions to perform.
|
||||
* @param sequence the TMS pin levels for each state transition, starting with
|
||||
* the least-significant bit.
|
||||
*/
|
||||
void jtag_clock_tms(u8 count, u8 sequence)
|
||||
{
|
||||
volatile u8 outb_buffer;
|
||||
u8 i;
|
||||
|
||||
outb_buffer = OUTB & ~(PIN_TCK);
|
||||
|
||||
for ( i = 0; i < count; i++ ) {
|
||||
/* Set TMS pin according to sequence parameter */
|
||||
if ( sequence & 0x1 ) {
|
||||
outb_buffer |= PIN_TMS;
|
||||
}
|
||||
else {
|
||||
outb_buffer &= ~PIN_TMS;
|
||||
}
|
||||
|
||||
OUTB = outb_buffer;
|
||||
sequence = sequence >> 1;
|
||||
OUTB = outb_buffer | PIN_TCK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform TAP-FSM state transitions at less than maximum TCK frequency.
|
||||
*
|
||||
* @param count the number of state transitions to perform.
|
||||
* @param sequence the TMS pin levels for each state transition, starting with
|
||||
* the least-significant bit.
|
||||
*/
|
||||
void jtag_slow_clock_tms(u8 count, u8 sequence)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current JTAG signal states.
|
||||
*
|
||||
* @return a 16-bit integer where the most-significant byte contains the state
|
||||
* of the JTAG input signals and the least-significant byte cotains the state
|
||||
* of the JTAG output signals.
|
||||
*/
|
||||
u16 jtag_get_signals(void)
|
||||
{
|
||||
u8 input_signal_state, output_signal_state;
|
||||
|
||||
input_signal_state = 0;
|
||||
output_signal_state = 0;
|
||||
|
||||
/* Get states of input pins */
|
||||
if (GET_TDO()) {
|
||||
input_signal_state |= SIGNAL_TDO;
|
||||
}
|
||||
if (GET_BRKOUT()) {
|
||||
input_signal_state |= SIGNAL_BRKOUT;
|
||||
}
|
||||
if (GET_TRAP()) {
|
||||
input_signal_state |= SIGNAL_TRAP;
|
||||
}
|
||||
if (GET_RTCK()) {
|
||||
/* Using RTCK this way would be extremely slow,
|
||||
* implemented only for the sake of completeness */
|
||||
input_signal_state |= SIGNAL_RTCK;
|
||||
}
|
||||
|
||||
/* Get states of output pins */
|
||||
output_signal_state = PINSB & MASK_PORTB_DIRECTION_OUT;
|
||||
|
||||
return ((u16)input_signal_state << 8) | ((u16)output_signal_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set state of JTAG output signals.
|
||||
*
|
||||
* @param low signals which should be de-asserted.
|
||||
* @param high signals which should be asserted.
|
||||
*/
|
||||
void jtag_set_signals(u8 low, u8 high)
|
||||
{
|
||||
OUTB &= ~(low & MASK_PORTB_DIRECTION_OUT);
|
||||
OUTB |= (high & MASK_PORTB_DIRECTION_OUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure TCK delay parameters.
|
||||
*
|
||||
* @param scan number of delay cycles in shift operations.
|
||||
* @param tck number of delay cycles in clock_tck operations.
|
||||
* @param tms number of delay cycles in clock_tms operations.
|
||||
*/
|
||||
void jtag_configure_tck_delay(u8 scan, u8 tck, u8 tms)
|
||||
{
|
||||
delay_scan = scan;
|
||||
delay_tck = tck;
|
||||
delay_tms = tms;
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Martin Schmoelzer *
|
||||
* <martin.schmoelzer@student.tuwien.ac.at> *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#include "shorttypes.h"
|
||||
#include "io.h"
|
||||
#include "usb.h"
|
||||
#include "protocol.h"
|
||||
|
||||
extern void sudav_isr(void) __interrupt SUDAV_ISR;
|
||||
extern void sof_isr(void) __interrupt;
|
||||
extern void sutok_isr(void) __interrupt;
|
||||
extern void suspend_isr(void) __interrupt;
|
||||
extern void usbreset_isr(void) __interrupt;
|
||||
extern void ibn_isr(void) __interrupt;
|
||||
extern void ep0in_isr(void) __interrupt;
|
||||
extern void ep0out_isr(void) __interrupt;
|
||||
extern void ep1in_isr(void) __interrupt;
|
||||
extern void ep1out_isr(void) __interrupt;
|
||||
extern void ep2in_isr(void) __interrupt;
|
||||
extern void ep2out_isr(void) __interrupt;
|
||||
extern void ep3in_isr(void) __interrupt;
|
||||
extern void ep3out_isr(void) __interrupt;
|
||||
extern void ep4in_isr(void) __interrupt;
|
||||
extern void ep4out_isr(void) __interrupt;
|
||||
extern void ep5in_isr(void) __interrupt;
|
||||
extern void ep5out_isr(void) __interrupt;
|
||||
extern void ep6in_isr(void) __interrupt;
|
||||
extern void ep6out_isr(void) __interrupt;
|
||||
extern void ep7in_isr(void) __interrupt;
|
||||
extern void ep7out_isr(void) __interrupt;
|
||||
|
||||
void io_init(void)
|
||||
{
|
||||
/* PORTxCFG register bits select alternate functions (1 == alternate function,
|
||||
* 0 == standard I/O)
|
||||
* OEx register bits turn on/off output buffer (1 == output, 0 == input)
|
||||
* OUTx register bits determine pin state of output
|
||||
* PINx register bits reflect pin state (high == 1, low == 0) */
|
||||
|
||||
/* PORT A */
|
||||
PORTACFG = PIN_OE;
|
||||
OEA = PIN_U_OE | PIN_OE | PIN_RUN_LED | PIN_COM_LED;
|
||||
OUTA = PIN_RUN_LED | PIN_COM_LED;
|
||||
|
||||
/* PORT B */
|
||||
PORTBCFG = 0x00;
|
||||
OEB = PIN_TDI | PIN_TMS | PIN_TCK | PIN_TRST | PIN_BRKIN | PIN_RESET
|
||||
| PIN_OCDSE;
|
||||
|
||||
/* TRST and RESET signals are low-active but inverted by hardware, so we clear
|
||||
* these signals here! */
|
||||
OUTB = 0x00;
|
||||
|
||||
/* PORT C */
|
||||
PORTCCFG = PIN_WR;
|
||||
OEC = PIN_TXD0 | PIN_WR;
|
||||
OUTC = 0x00;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
io_init();
|
||||
usb_init();
|
||||
|
||||
/* Enable Interrupts */
|
||||
EA = 1;
|
||||
|
||||
/* Begin executing command(s). This function never returns. */
|
||||
command_loop();
|
||||
|
||||
/* Never reached, but SDCC complains about missing return statement */
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Martin Schmoelzer *
|
||||
* <martin.schmoelzer@student.tuwien.ac.at> *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#include "protocol.h"
|
||||
#include "jtag.h"
|
||||
#include "delay.h"
|
||||
#include "usb.h"
|
||||
#include "io.h"
|
||||
#include "msgtypes.h"
|
||||
|
||||
#include "reg_ezusb.h"
|
||||
|
||||
/**
|
||||
* @file Implementation of the OpenULINK communication protocol.
|
||||
*
|
||||
* The OpenULINK protocol uses one OUT and one IN endpoint. These two endpoints
|
||||
* are configured to use the maximum packet size for full-speed transfers,
|
||||
* 64 bytes. Commands always start with a command ID (see msgtypes.h for
|
||||
* command ID definitions) and contain zero or more payload data bytes in both
|
||||
* transfer directions (IN and OUT). The payload
|
||||
*
|
||||
* Almost all commands contain a fixed number of payload data bytes. The number
|
||||
* of payload data bytes for the IN and OUT direction does not need to be the
|
||||
* same.
|
||||
*
|
||||
* Multiple commands may be sent in one EP2 Bulk-OUT packet. Because the
|
||||
* OpenULINK firmware does not perform bounds checking for EP2 Bulk-IN packets,
|
||||
* the host MUST ensure that the commands sent in the OUT packet require a
|
||||
* maximum of 64 bytes of IN data.
|
||||
*/
|
||||
|
||||
/** Index in EP2 Bulk-OUT data buffer that contains the current command ID */
|
||||
volatile u8 cmd_id_index;
|
||||
|
||||
/** Number of data bytes already in EP2 Bulk-IN buffer */
|
||||
volatile u8 payload_index_in;
|
||||
|
||||
/**
|
||||
* Execute a SET_LEDS command.
|
||||
*/
|
||||
void execute_set_led_command(void)
|
||||
{
|
||||
u8 led_state = OUT2BUF[cmd_id_index + 1];
|
||||
|
||||
if (led_state & RUN_LED_ON) {
|
||||
SET_RUN_LED();
|
||||
}
|
||||
|
||||
if (led_state & COM_LED_ON) {
|
||||
SET_COM_LED();
|
||||
}
|
||||
|
||||
if (led_state & RUN_LED_OFF) {
|
||||
CLEAR_RUN_LED();
|
||||
}
|
||||
|
||||
if (led_state & COM_LED_OFF) {
|
||||
CLEAR_COM_LED();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes one command and updates global command indexes.
|
||||
*
|
||||
* @param index the index of the Bulk EP2-OUT data buffer at which the
|
||||
* command ID is stored.
|
||||
* @return true if this command was the last command.
|
||||
* @return false if there are more commands within the current contents of the
|
||||
* Bulk EP2-OUT data buffer.
|
||||
*/
|
||||
bool execute_command(void)
|
||||
{
|
||||
u8 usb_out_bytecount, usb_in_bytecount;
|
||||
u16 signal_state;
|
||||
u16 count;
|
||||
|
||||
/* Most commands do not transfer IN data. To save code space, we write 0 to
|
||||
* usb_in_bytecount here, then modify it in the switch statement below where
|
||||
* neccessary */
|
||||
usb_in_bytecount = 0;
|
||||
|
||||
switch (OUT2BUF[cmd_id_index] /* Command ID */) {
|
||||
case CMD_SCAN_IN:
|
||||
usb_out_bytecount = 5;
|
||||
usb_in_bytecount = OUT2BUF[cmd_id_index + 1];
|
||||
jtag_scan_in(cmd_id_index + 1, payload_index_in);
|
||||
break;
|
||||
case CMD_SCAN_OUT:
|
||||
usb_out_bytecount = OUT2BUF[cmd_id_index + 1] + 5;
|
||||
jtag_scan_out(cmd_id_index + 1);
|
||||
break;
|
||||
case CMD_SCAN_IO:
|
||||
usb_in_bytecount = OUT2BUF[cmd_id_index + 1];
|
||||
usb_out_bytecount = usb_in_bytecount + 5;
|
||||
jtag_scan_io(cmd_id_index + 1, payload_index_in);
|
||||
break;
|
||||
case CMD_CLOCK_TMS:
|
||||
usb_out_bytecount = 2;
|
||||
jtag_clock_tms(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]);
|
||||
break;
|
||||
case CMD_CLOCK_TCK:
|
||||
usb_out_bytecount = 2;
|
||||
count = (u16)OUT2BUF[cmd_id_index + 1];
|
||||
count |= ((u16)OUT2BUF[cmd_id_index + 2]) << 8;
|
||||
jtag_clock_tck(count);
|
||||
break;
|
||||
case CMD_SLEEP_US:
|
||||
usb_out_bytecount = 2;
|
||||
count = (u16)OUT2BUF[cmd_id_index + 1];
|
||||
count |= ((u16)OUT2BUF[cmd_id_index + 2]) << 8;
|
||||
delay_us(count);
|
||||
break;
|
||||
case CMD_SLEEP_MS:
|
||||
usb_out_bytecount = 2;
|
||||
count = (u16)OUT2BUF[cmd_id_index + 1];
|
||||
count |= ((u16)OUT2BUF[cmd_id_index + 2]) << 8;
|
||||
delay_ms(count);
|
||||
break;
|
||||
case CMD_GET_SIGNALS:
|
||||
usb_out_bytecount = 0;
|
||||
usb_in_bytecount = 2;
|
||||
signal_state = jtag_get_signals();
|
||||
IN2BUF[payload_index_in] = (signal_state >> 8) & 0x00FF;
|
||||
IN2BUF[payload_index_in + 1] = signal_state & 0x00FF;
|
||||
break;
|
||||
case CMD_SET_SIGNALS:
|
||||
usb_out_bytecount = 2;
|
||||
jtag_set_signals(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]);
|
||||
break;
|
||||
case CMD_SET_LEDS:
|
||||
usb_out_bytecount = 1;
|
||||
execute_set_led_command();
|
||||
break;
|
||||
case CMD_TEST:
|
||||
usb_out_bytecount = 1;
|
||||
/* Do nothing... This command is only used to test if the device is ready
|
||||
* to accept new commands */
|
||||
break;
|
||||
default:
|
||||
/* Should never be reached */
|
||||
usb_out_bytecount = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Update EP2 Bulk-IN data byte count */
|
||||
payload_index_in += usb_in_bytecount;
|
||||
|
||||
/* Determine if this was the last command */
|
||||
if ((cmd_id_index + usb_out_bytecount + 1) >= OUT2BC) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
/* Not the last command, update cmd_id_index */
|
||||
cmd_id_index += (usb_out_bytecount + 1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forever wait for commands and execute them as they arrive.
|
||||
*/
|
||||
void command_loop(void)
|
||||
{
|
||||
bool last_command;
|
||||
|
||||
while (1) {
|
||||
cmd_id_index = 0;
|
||||
payload_index_in = 0;
|
||||
|
||||
/* Wait until host sends EP2 Bulk-OUT packet */
|
||||
while (!EP2_out);
|
||||
EP2_out = 0;
|
||||
|
||||
/* Turn on COM LED to indicate command execution */
|
||||
SET_COM_LED();
|
||||
|
||||
/* Execute the commands */
|
||||
last_command = false;
|
||||
while (last_command == false) {
|
||||
last_command = execute_command();
|
||||
}
|
||||
|
||||
CLEAR_COM_LED();
|
||||
|
||||
/* Send back EP2 Bulk-IN packet if required */
|
||||
if (payload_index_in > 0) {
|
||||
IN2BC = payload_index_in;
|
||||
while (!EP2_in);
|
||||
EP2_in = 0;
|
||||
}
|
||||
|
||||
/* Re-arm EP2-OUT after command execution */
|
||||
OUT2BC = 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,543 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Martin Schmoelzer *
|
||||
* <martin.schmoelzer@student.tuwien.ac.at> *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
/**
|
||||
* @file Defines USB descriptors, interrupt routines and helper functions.
|
||||
* To minimize code size, we make the following assumptions:
|
||||
* - The OpenULINK has exactly one configuration
|
||||
* - and exactly one alternate setting
|
||||
*
|
||||
* Therefore, we do not have to support the Set Configuration USB request.
|
||||
*/
|
||||
|
||||
#include "usb.h"
|
||||
#include "delay.h"
|
||||
#include "io.h"
|
||||
|
||||
/* Also update external declarations in "include/usb.h" if making changes to
|
||||
* these variables! */
|
||||
volatile bool EP2_out = 0;
|
||||
volatile bool EP2_in = 0;
|
||||
|
||||
volatile __xdata __at 0x7FE8 setup_data_t setup_data;
|
||||
|
||||
/* Define number of endpoints (except Control Endpoint 0) in a central place.
|
||||
* Be sure to include the neccessary endpoint descriptors! */
|
||||
#define NUM_ENDPOINTS 2
|
||||
|
||||
/*
|
||||
* Normally, we would initialize the descriptor structures in C99 style:
|
||||
*
|
||||
* __code usb_device_descriptor_t device_descriptor = {
|
||||
* .bLength = foo,
|
||||
* .bDescriptorType = bar,
|
||||
* .bcdUSB = 0xABCD,
|
||||
* ...
|
||||
* };
|
||||
*
|
||||
* But SDCC currently does not support this, so we have to do it the
|
||||
* old-fashioned way...
|
||||
*/
|
||||
|
||||
__code usb_device_descriptor_t device_descriptor = {
|
||||
/* .bLength = */ sizeof(usb_device_descriptor_t),
|
||||
/* .bDescriptorType = */ DESCRIPTOR_TYPE_DEVICE,
|
||||
/* .bcdUSB = */ 0x0110, /* BCD: 01.00 (Version 1.0 USB spec) */
|
||||
/* .bDeviceClass = */ 0xFF, /* 0xFF = vendor-specific */
|
||||
/* .bDeviceSubClass = */ 0xFF,
|
||||
/* .bDeviceProtocol = */ 0xFF,
|
||||
/* .bMaxPacketSize0 = */ 64,
|
||||
/* .idVendor = */ 0xC251,
|
||||
/* .idProduct = */ 0x2710,
|
||||
/* .bcdDevice = */ 0x0100,
|
||||
/* .iManufacturer = */ 1,
|
||||
/* .iProduct = */ 2,
|
||||
/* .iSerialNumber = */ 3,
|
||||
/* .bNumConfigurations = */ 1
|
||||
};
|
||||
|
||||
/* WARNING: ALL config, interface and endpoint descriptors MUST be adjacent! */
|
||||
|
||||
__code usb_config_descriptor_t config_descriptor = {
|
||||
/* .bLength = */ sizeof(usb_config_descriptor_t),
|
||||
/* .bDescriptorType = */ DESCRIPTOR_TYPE_CONFIGURATION,
|
||||
/* .wTotalLength = */ sizeof(usb_config_descriptor_t) +
|
||||
sizeof(usb_interface_descriptor_t) +
|
||||
NUM_ENDPOINTS * sizeof(usb_endpoint_descriptor_t),
|
||||
/* .bNumInterfaces = */ 1,
|
||||
/* .bConfigurationValue = */ 1,
|
||||
/* .iConfiguration = */ 4, /* String describing this configuration */
|
||||
/* .bmAttributes = */ 0x80, /* Only MSB set according to USB spec */
|
||||
/* .MaxPower = */ 50 /* 100 mA */
|
||||
};
|
||||
|
||||
__code usb_interface_descriptor_t interface_descriptor00 = {
|
||||
/* .bLength = */ sizeof(usb_interface_descriptor_t),
|
||||
/* .bDescriptorType = */ DESCRIPTOR_TYPE_INTERFACE,
|
||||
/* .bInterfaceNumber = */ 0,
|
||||
/* .bAlternateSetting = */ 0,
|
||||
/* .bNumEndpoints = */ NUM_ENDPOINTS,
|
||||
/* .bInterfaceClass = */ 0xFF,
|
||||
/* .bInterfaceSubclass = */ 0xFF,
|
||||
/* .bInterfaceProtocol = */ 0xFF,
|
||||
/* .iInterface = */ 0
|
||||
};
|
||||
|
||||
__code usb_endpoint_descriptor_t Bulk_EP2_IN_Endpoint_Descriptor = {
|
||||
/* .bLength = */ sizeof(usb_endpoint_descriptor_t),
|
||||
/* .bDescriptorType = */ 0x05,
|
||||
/* .bEndpointAddress = */ 2 | USB_DIR_IN,
|
||||
/* .bmAttributes = */ 0x02,
|
||||
/* .wMaxPacketSize = */ 64,
|
||||
/* .bInterval = */ 0
|
||||
};
|
||||
|
||||
__code usb_endpoint_descriptor_t Bulk_EP2_OUT_Endpoint_Descriptor = {
|
||||
/* .bLength = */ sizeof(usb_endpoint_descriptor_t),
|
||||
/* .bDescriptorType = */ 0x05,
|
||||
/* .bEndpointAddress = */ 2 | USB_DIR_OUT,
|
||||
/* .bmAttributes = */ 0x02,
|
||||
/* .wMaxPacketSize = */ 64,
|
||||
/* .bInterval = */ 0
|
||||
};
|
||||
|
||||
__code usb_language_descriptor_t language_descriptor = {
|
||||
/* .bLength = */ 4,
|
||||
/* .bDescriptorType = */ DESCRIPTOR_TYPE_STRING,
|
||||
/* .wLANGID = */ {0x0409 /* US English */}
|
||||
};
|
||||
|
||||
__code usb_string_descriptor_t strManufacturer = STR_DESCR(9,'O','p','e','n','U','L','I','N','K');
|
||||
__code usb_string_descriptor_t strProduct = STR_DESCR(9,'O','p','e','n','U','L','I','N','K');
|
||||
__code usb_string_descriptor_t strSerialNumber = STR_DESCR(6, '0','0','0','0','0','1');
|
||||
__code usb_string_descriptor_t strConfigDescr = STR_DESCR(12, 'J','T','A','G',' ','A','d','a','p','t','e','r');
|
||||
|
||||
/* Table containing pointers to string descriptors */
|
||||
__code usb_string_descriptor_t* __code en_string_descriptors[4] = {
|
||||
&strManufacturer,
|
||||
&strProduct,
|
||||
&strSerialNumber,
|
||||
&strConfigDescr
|
||||
};
|
||||
|
||||
void sudav_isr(void) __interrupt SUDAV_ISR
|
||||
{
|
||||
CLEAR_IRQ();
|
||||
|
||||
usb_handle_setup_data();
|
||||
|
||||
USBIRQ = SUDAVIR;
|
||||
EP0CS |= HSNAK;
|
||||
}
|
||||
|
||||
void sof_isr(void) __interrupt SOF_ISR { }
|
||||
void sutok_isr(void) __interrupt SUTOK_ISR { }
|
||||
void suspend_isr(void) __interrupt SUSPEND_ISR { }
|
||||
void usbreset_isr(void) __interrupt USBRESET_ISR { }
|
||||
void ibn_isr(void) __interrupt IBN_ISR { }
|
||||
|
||||
void ep0in_isr(void) __interrupt EP0IN_ISR { }
|
||||
void ep0out_isr(void) __interrupt EP0OUT_ISR { }
|
||||
void ep1in_isr(void) __interrupt EP1IN_ISR { }
|
||||
void ep1out_isr(void) __interrupt EP1OUT_ISR { }
|
||||
|
||||
/**
|
||||
* EP2 IN: called after the transfer from uC->Host has finished: we sent data
|
||||
*/
|
||||
void ep2in_isr(void) __interrupt EP2IN_ISR {
|
||||
EP2_in = 1;
|
||||
|
||||
CLEAR_IRQ();
|
||||
IN07IRQ = IN2IR; // Clear OUT2 IRQ
|
||||
}
|
||||
|
||||
/**
|
||||
* EP2 OUT: called after the transfer from Host->uC has finished: we got data
|
||||
*/
|
||||
void ep2out_isr(void) __interrupt EP2OUT_ISR {
|
||||
EP2_out = 1;
|
||||
|
||||
CLEAR_IRQ();
|
||||
OUT07IRQ = OUT2IR; // Clear OUT2 IRQ
|
||||
}
|
||||
|
||||
void ep3in_isr(void) __interrupt EP3IN_ISR { }
|
||||
void ep3out_isr(void) __interrupt EP3OUT_ISR { }
|
||||
void ep4in_isr(void) __interrupt EP4IN_ISR { }
|
||||
void ep4out_isr(void) __interrupt EP4OUT_ISR { }
|
||||
void ep5in_isr(void) __interrupt EP5IN_ISR { }
|
||||
void ep5out_isr(void) __interrupt EP5OUT_ISR { }
|
||||
void ep6in_isr(void) __interrupt EP6IN_ISR { }
|
||||
void ep6out_isr(void) __interrupt EP6OUT_ISR { }
|
||||
void ep7in_isr(void) __interrupt EP7IN_ISR { }
|
||||
void ep7out_isr(void) __interrupt EP7OUT_ISR { }
|
||||
|
||||
/**
|
||||
* Return the control/status register for an endpoint
|
||||
*
|
||||
* @param ep endpoint address
|
||||
* @return on success: pointer to Control & Status register for endpoint
|
||||
* specified in \a ep
|
||||
* @return on failure: NULL
|
||||
*/
|
||||
__xdata u8* usb_get_endpoint_cs_reg(u8 ep)
|
||||
{
|
||||
/* Mask direction bit */
|
||||
u8 ep_num = ep & 0x7F;
|
||||
|
||||
switch (ep_num) {
|
||||
case 0:
|
||||
return &EP0CS;
|
||||
break;
|
||||
case 1:
|
||||
return ep & 0x80 ? &IN1CS : &OUT1CS;
|
||||
break;
|
||||
case 2:
|
||||
return ep & 0x80 ? &IN2CS : &OUT2CS;
|
||||
break;
|
||||
case 3:
|
||||
return ep & 0x80 ? &IN3CS : &OUT3CS;
|
||||
break;
|
||||
case 4:
|
||||
return ep & 0x80 ? &IN4CS : &OUT4CS;
|
||||
break;
|
||||
case 5:
|
||||
return ep & 0x80 ? &IN5CS : &OUT5CS;
|
||||
break;
|
||||
case 6:
|
||||
return ep & 0x80 ? &IN6CS : &OUT6CS;
|
||||
break;
|
||||
case 7:
|
||||
return ep & 0x80 ? &IN7CS : &OUT7CS;
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void usb_reset_data_toggle(u8 ep)
|
||||
{
|
||||
/* TOGCTL register:
|
||||
+----+-----+-----+------+-----+-------+-------+-------+
|
||||
| Q | S | R | IO | 0 | EP2 | EP1 | EP0 |
|
||||
+----+-----+-----+------+-----+-------+-------+-------+
|
||||
|
||||
To reset data toggle bits, we have to write the endpoint direction (IN/OUT)
|
||||
to the IO bit and the endpoint number to the EP2..EP0 bits. Then, in a
|
||||
separate write cycle, the R bit needs to be set.
|
||||
*/
|
||||
u8 togctl_value = (ep & 0x80 >> 3) | (ep & 0x7);
|
||||
|
||||
/* First step: Write EP number and direction bit */
|
||||
TOGCTL = togctl_value;
|
||||
|
||||
/* Second step: Set R bit */
|
||||
togctl_value |= TOG_R;
|
||||
TOGCTL = togctl_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle GET_STATUS request.
|
||||
*
|
||||
* @return on success: true
|
||||
* @return on failure: false
|
||||
*/
|
||||
bool usb_handle_get_status(void)
|
||||
{
|
||||
u8 *ep_cs;
|
||||
|
||||
switch (setup_data.bmRequestType) {
|
||||
case GS_DEVICE:
|
||||
/* Two byte response: Byte 0, Bit 0 = self-powered, Bit 1 = remote wakeup.
|
||||
* Byte 1: reserved, reset to zero */
|
||||
IN0BUF[0] = 0;
|
||||
IN0BUF[1] = 0;
|
||||
|
||||
/* Send response */
|
||||
IN0BC = 2;
|
||||
break;
|
||||
case GS_INTERFACE:
|
||||
/* Always return two zero bytes according to USB 1.1 spec, p. 191 */
|
||||
IN0BUF[0] = 0;
|
||||
IN0BUF[1] = 0;
|
||||
|
||||
/* Send response */
|
||||
IN0BC = 2;
|
||||
break;
|
||||
case GS_ENDPOINT:
|
||||
/* Get stall bit for endpoint specified in low byte of wIndex */
|
||||
ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex & 0xff);
|
||||
|
||||
if (*ep_cs & EPSTALL) {
|
||||
IN0BUF[0] = 0x01;
|
||||
}
|
||||
else {
|
||||
IN0BUF[0] = 0x00;
|
||||
}
|
||||
|
||||
/* Second byte sent has to be always zero */
|
||||
IN0BUF[1] = 0;
|
||||
|
||||
/* Send response */
|
||||
IN0BC = 2;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle CLEAR_FEATURE request.
|
||||
*
|
||||
* @return on success: true
|
||||
* @return on failure: false
|
||||
*/
|
||||
bool usb_handle_clear_feature(void)
|
||||
{
|
||||
__xdata u8 *ep_cs;
|
||||
|
||||
switch (setup_data.bmRequestType) {
|
||||
case CF_DEVICE:
|
||||
/* Clear remote wakeup not supported: stall EP0 */
|
||||
STALL_EP0();
|
||||
break;
|
||||
case CF_ENDPOINT:
|
||||
if (setup_data.wValue == 0) {
|
||||
/* Unstall the endpoint specified in wIndex */
|
||||
ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex);
|
||||
if (!ep_cs) {
|
||||
return false;
|
||||
}
|
||||
*ep_cs &= ~EPSTALL;
|
||||
}
|
||||
else {
|
||||
/* Unsupported feature, stall EP0 */
|
||||
STALL_EP0();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Vendor commands... */
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle SET_FEATURE request.
|
||||
*
|
||||
* @return on success: true
|
||||
* @return on failure: false
|
||||
*/
|
||||
bool usb_handle_set_feature(void)
|
||||
{
|
||||
__xdata u8 *ep_cs;
|
||||
|
||||
switch (setup_data.bmRequestType) {
|
||||
case SF_DEVICE:
|
||||
if (setup_data.wValue == 2) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SF_ENDPOINT:
|
||||
if (setup_data.wValue == 0) {
|
||||
/* Stall the endpoint specified in wIndex */
|
||||
ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex);
|
||||
if (!ep_cs) {
|
||||
return false;
|
||||
}
|
||||
*ep_cs |= EPSTALL;
|
||||
}
|
||||
else {
|
||||
/* Unsupported endpoint feature */
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Vendor commands... */
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle GET_DESCRIPTOR request.
|
||||
*
|
||||
* @return on success: true
|
||||
* @return on failure: false
|
||||
*/
|
||||
bool usb_handle_get_descriptor(void)
|
||||
{
|
||||
__xdata u8 descriptor_type;
|
||||
__xdata u8 descriptor_index;
|
||||
|
||||
descriptor_type = (setup_data.wValue & 0xff00) >> 8;
|
||||
descriptor_index = setup_data.wValue & 0x00ff;
|
||||
|
||||
switch (descriptor_type) {
|
||||
case DESCRIPTOR_TYPE_DEVICE:
|
||||
SUDPTRH = HI8(&device_descriptor);
|
||||
SUDPTRL = LO8(&device_descriptor);
|
||||
break;
|
||||
case DESCRIPTOR_TYPE_CONFIGURATION:
|
||||
SUDPTRH = HI8(&config_descriptor);
|
||||
SUDPTRL = LO8(&config_descriptor);
|
||||
break;
|
||||
case DESCRIPTOR_TYPE_STRING:
|
||||
if (setup_data.wIndex == 0) {
|
||||
/* Supply language descriptor */
|
||||
SUDPTRH = HI8(&language_descriptor);
|
||||
SUDPTRL = LO8(&language_descriptor);
|
||||
}
|
||||
else if (setup_data.wIndex == 0x0409 /* US English */) {
|
||||
/* Supply string descriptor */
|
||||
SUDPTRH = HI8(en_string_descriptors[descriptor_index - 1]);
|
||||
SUDPTRL = LO8(en_string_descriptors[descriptor_index - 1]);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Unsupported descriptor type */
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle SET_INTERFACE request.
|
||||
*/
|
||||
void usb_handle_set_interface(void)
|
||||
{
|
||||
/* Reset Data Toggle */
|
||||
usb_reset_data_toggle(USB_DIR_IN | 2);
|
||||
usb_reset_data_toggle(USB_DIR_OUT | 2);
|
||||
|
||||
/* Unstall & clear busy flag of all valid IN endpoints */
|
||||
IN2CS = 0 | EPBSY;
|
||||
|
||||
/* Unstall all valid OUT endpoints, reset bytecounts */
|
||||
OUT2CS = 0;
|
||||
OUT2BC = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the arrival of a USB Control Setup Packet.
|
||||
*/
|
||||
void usb_handle_setup_data(void)
|
||||
{
|
||||
switch (setup_data.bRequest) {
|
||||
case GET_STATUS:
|
||||
if (!usb_handle_get_status()) {
|
||||
STALL_EP0();
|
||||
}
|
||||
break;
|
||||
case CLEAR_FEATURE:
|
||||
if (!usb_handle_clear_feature()) {
|
||||
STALL_EP0();
|
||||
}
|
||||
break;
|
||||
case 2: case 4:
|
||||
/* Reserved values */
|
||||
STALL_EP0();
|
||||
break;
|
||||
case SET_FEATURE:
|
||||
if (!usb_handle_set_feature()) {
|
||||
STALL_EP0();
|
||||
}
|
||||
break;
|
||||
case SET_ADDRESS:
|
||||
/* Handled by USB core */
|
||||
break;
|
||||
case SET_DESCRIPTOR:
|
||||
/* Set Descriptor not supported. */
|
||||
STALL_EP0();
|
||||
break;
|
||||
case GET_DESCRIPTOR:
|
||||
if (!usb_handle_get_descriptor()) {
|
||||
STALL_EP0();
|
||||
}
|
||||
break;
|
||||
case GET_CONFIGURATION:
|
||||
/* OpenULINK has only one configuration, return its index */
|
||||
IN0BUF[0] = config_descriptor.bConfigurationValue;
|
||||
IN0BC = 1;
|
||||
break;
|
||||
case SET_CONFIGURATION:
|
||||
/* OpenULINK has only one configuration -> nothing to do */
|
||||
break;
|
||||
case GET_INTERFACE:
|
||||
/* OpenULINK only has one interface, return its number */
|
||||
IN0BUF[0] = interface_descriptor00.bInterfaceNumber;
|
||||
IN0BC = 1;
|
||||
break;
|
||||
case SET_INTERFACE:
|
||||
usb_handle_set_interface();
|
||||
break;
|
||||
case SYNCH_FRAME:
|
||||
/* Isochronous endpoints not used -> nothing to do */
|
||||
break;
|
||||
default:
|
||||
/* Any other requests: do nothing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* USB initialization. Configures USB interrupts, endpoints and performs
|
||||
* ReNumeration.
|
||||
*/
|
||||
void usb_init(void) {
|
||||
/* Mark endpoint 2 IN & OUT as valid */
|
||||
IN07VAL = IN2VAL;
|
||||
OUT07VAL = OUT2VAL;
|
||||
|
||||
/* Make sure no isochronous endpoints are marked valid */
|
||||
INISOVAL = 0;
|
||||
OUTISOVAL = 0;
|
||||
|
||||
/* Disable isochronous endpoints. This makes the isochronous data buffers
|
||||
* available as 8051 XDATA memory at address 0x2000 - 0x27FF */
|
||||
ISOCTL = ISODISAB;
|
||||
|
||||
/* Enable USB Autovectoring */
|
||||
USBBAV |= AVEN;
|
||||
|
||||
/* Enable SUDAV interrupt */
|
||||
USBIEN |= SUDAVIE;
|
||||
|
||||
/* Enable EP2 OUT & IN interrupts */
|
||||
OUT07IEN = OUT2IEN;
|
||||
IN07IEN = IN2IEN;
|
||||
|
||||
/* Enable USB interrupt (EIE register) */
|
||||
EUSB = 1;
|
||||
|
||||
/* Perform ReNumeration */
|
||||
USBCS = DISCON | RENUM;
|
||||
delay_ms(200);
|
||||
USBCS = DISCOE | RENUM;
|
||||
}
|
|
@ -0,0 +1,251 @@
|
|||
:040000000200733255
|
||||
:01000B0032C2
|
||||
:0100130032BA
|
||||
:01001B0032B2
|
||||
:0100230032AA
|
||||
:01002B0032A2
|
||||
:01003300329A
|
||||
:01003B003292
|
||||
:01004300328A
|
||||
:01004B003282
|
||||
:01005300327A
|
||||
:01005B003272
|
||||
:01006300326A
|
||||
:03006B0002011F70
|
||||
:0300D90002006EB4
|
||||
:05006E0012011080FEEC
|
||||
:1000DC00907F937404F0907F9C7495F0907F96744D
|
||||
:1000EC0090F0907F94E4F0907F9D747FF0907F97D8
|
||||
:1000FC00E4F0907F957440F0907F9E7442F0907F76
|
||||
:10010C0098E4F0221200DC1204FCD2AF1207C89063
|
||||
:03011C00000022BE
|
||||
:0400CC00C200C201AB
|
||||
:10011F00C021C0E0C0F0C082C083C002C003C004D1
|
||||
:10012F00C005C006C007C000C001C0D075D00053C5
|
||||
:10013F0091EF120455907FAB7401F0907FB4E044BF
|
||||
:10014F0002F0D0D0D001D000D007D006D005D00417
|
||||
:10015F00D003D002D083D082D0F0D0E0D021323281
|
||||
:10016F003232323232323232C0E0C082C083D201F8
|
||||
:10017F005391EF907FA97404F0D083D082D0E032F6
|
||||
:10018F00C0E0C082C083D2005391EF907FAA740465
|
||||
:10019F00F0D083D082D0E032323232323232323249
|
||||
:1001AF003232AA82747F5AFB7407B50300500302E0
|
||||
:1001BF000269EB2B2B9001C8730201E00201E402EC
|
||||
:1001CF0001F702020A02021D02023002024302027A
|
||||
:1001DF0056907FB422EA30E7067BB67C7F80047BA3
|
||||
:1001EF00C67C7F8B828C8322EA30E7067BB87C7FCC
|
||||
:1001FF0080047BC87C7F8B828C8322EA30E7067B6E
|
||||
:10020F00BA7C7F80047BCA7C7F8B828C8322EA300E
|
||||
:10021F00E7067BBC7C7F80047BCC7C7F8B828C83CE
|
||||
:10022F0022EA30E7067BBE7C7F80047BCE7C7F8B0F
|
||||
:10023F00828C8322EA30E7067BC07C7F80047BD0F0
|
||||
:10024F007C7F8B828C8322EA30E7067AC27B7F80A9
|
||||
:10025F00047AD27B7F8A828B832290000022AA822B
|
||||
:10026F0074105AFB74075A4203907FD7EBF0742037
|
||||
:10027F004BF022907FE8E0FABA8002800ABA81023E
|
||||
:10028F008016BA825D8022907F00E4F0907F01F0AB
|
||||
:10029F00907FB57402F0804C907F00E4F0907F0166
|
||||
:1002AF00F0907FB57402F0803B907FECE0FAA3E012
|
||||
:1002BF008A821201B1AA82AB837C008A828B838CE3
|
||||
:1002CF00F0120D90FA30E008907F007401F0800575
|
||||
:1002DF00907F00E4F0907F01E4F0907FB57402F01E
|
||||
:1002EF008002C322D322907FE8E0FA6005BA02466B
|
||||
:1002FF00800A907FB4E0FA4401F0803A907FEAE000
|
||||
:10030F00FAA3E0FB4A7027907FECE0FAA3E08A8221
|
||||
:10031F001201B1AA82AB83EA4B7002C3228A828B8D
|
||||
:10032F0083E0FC5304FE8A828B83ECF08008907F7D
|
||||
:10033F00B4E0FA4401F0D322907FE8E0FA6005BA06
|
||||
:10034F0002468010907FEAE0FAA3E0FBBA0239BBC5
|
||||
:10035F000036D322907FEAE0FAA3E0FB4A702790A1
|
||||
:10036F007FECE0FAA3E08A821201B1AA82AB83EAA2
|
||||
:10037F004B7002C3228A828B83E0FC4304018A8282
|
||||
:10038F008B83ECF08002C322D322907FEAE0A3E0BC
|
||||
:10039F00FA907FEAE0FBA3E07C00BA0102800CBA7E
|
||||
:1003AF000202801DBA0302802E807B7AB07C0D90F2
|
||||
:1003BF007FD4ECF07AB07C0D7C00907FD5EAF08092
|
||||
:1003CF00677AC27C0D907FD4ECF07AC27C0D7C00F2
|
||||
:1003DF00907FD5EAF08051907FECE0FAA3E0FC4AE1
|
||||
:1003EF0070167AE27C0D907FD4ECF07AE27C0D7C73
|
||||
:1003FF0000907FD5EAF08030907FECE0FAA3E0FC2C
|
||||
:10040F00BA0921BC041E1BEB2BFA900E3693CAA31C
|
||||
:10041F0093FB8A048B05907FD4EDF07B00907FD502
|
||||
:10042F00EAF08004C322C322D32275828212026DA6
|
||||
:10043F0075820212026D907FB87402F0907FC8E44B
|
||||
:10044F00F0907FC9F022907FE9E0FA740CB50200BA
|
||||
:10045F00500122EA2A2A9004697302049002049E32
|
||||
:10046F000204AC0204B40204AC0204C10204CA02C6
|
||||
:10047F0004C20204D70204E70204E80204F80204EB
|
||||
:10048F00FB120282500122907FB4E04401F022124D
|
||||
:10049F0002F5500122907FB4E04401F022907FB426
|
||||
:1004AF00E04401F0221203474042907FB4E0440140
|
||||
:1004BF00F02222907FB4E04401F022120399402CE5
|
||||
:1004CF00907FB4E04401F022900DC7E493907F0039
|
||||
:1004DF00F0907FB57401F02222900DCDE493907FC0
|
||||
:1004EF0000F0907FB57401F02212043922907FDE64
|
||||
:1004FF007404F0907FDF7404F0907FE0E4F0907F5D
|
||||
:10050F00E1F0907FA17401F0907FAFE04401F09093
|
||||
:10051F007FAEE04401F0907FAD7404F0907FAC7437
|
||||
:10052F0004F0D2E8907FD6740AF09000C8120D3D07
|
||||
:07053F00907FD67406F02244
|
||||
:100DB00012011001FFFFFF4051C210270001010284
|
||||
:100DC000030109022000010104803209040000022D
|
||||
:100DD000FFFFFF00070582024000000705020240F6
|
||||
:100DE00000000403090414034F00700065006E0046
|
||||
:100DF00055004C0049004E004B0014034F0070009A
|
||||
:100E000065006E0055004C0049004E004B000E037B
|
||||
:100E10003000300030003000300031001A034A004A
|
||||
:100E20005400410047002000410064006100700050
|
||||
:0E0E3000740065007200E60DFA0D0E0E1C0E29
|
||||
:10054600E5080424C0F582E4347DF583E0FA30E161
|
||||
:1005560008907F96E0FB54EFF0EA30E008907F9633
|
||||
:10056600E0FB547FF0EA30E308907F96E0FB44100E
|
||||
:10057600F0EA30E208907F96E0FA4480F0227A00B2
|
||||
:10058600E50824C0F582E4347DF583E0FB603EBBDC
|
||||
:100596000202805FBB040302061CBB200302064363
|
||||
:1005A600BB2203020673BB23030206ACBB24030271
|
||||
:1005B60006E5BB250302071DBB260302074CBB2825
|
||||
:1005C6000302077BBB290302078A02078E7B05E528
|
||||
:1005D600080424C0F582E4347DF583E0FAE50804D6
|
||||
:1005E600F58285090DC002C003120805D003D002AA
|
||||
:1005F600020790E5080424C0F582E4347DF583E023
|
||||
:100606002405FBE50804F582C002C003120951D097
|
||||
:1006160003D002020790E5080424C0F582E4347D85
|
||||
:10062600F583E0FA2405FBE50804F582850917C081
|
||||
:1006360002C003120A83D003D0020207907B02E5B0
|
||||
:10064600080424C0F582E4347DF583E0FC740225B9
|
||||
:100656000824C0F582E4347DF583E0F5228C82C05F
|
||||
:1006660002C003120C5BD003D0020207907B02E5A6
|
||||
:10067600080424C0F582E4347DF583E0FC7D007433
|
||||
:1006860002250824C0F582E4347DF583E0FFE442C8
|
||||
:1006960004EF42058C828D83C002C003120C20D069
|
||||
:1006A60003D0020207907B02E5080424C0F582E429
|
||||
:1006B600347DF583E0FC7D007402250824C0F582B4
|
||||
:1006C600E4347DF583E0FFE44204EF42058C828D3D
|
||||
:1006D60083C002C003120D0AD003D0020207907B2A
|
||||
:1006E60002E5080424C0F582E4347DF583E0FC7D50
|
||||
:1006F600007402250824C0F582E4347DF583E0FF0A
|
||||
:10070600E44204EF42058C828D83C002C003120DC1
|
||||
:100716003DD003D00280737B007A02C002C0031270
|
||||
:100726000C95AC82AD83D003D00285098275837E99
|
||||
:100736008D06EEF0E509042400F582E4347EF583A7
|
||||
:100746007D00ECF080447B02E5080424C0F582E4D9
|
||||
:10075600347DF583E0FC7402250824C0F582E43478
|
||||
:100766007DF583E0F5228C82C002C003120CD8D03E
|
||||
:1007760003D00280157B01C002C003120546D003D8
|
||||
:10078600D00280067B0180027B00EA2509F509AAD2
|
||||
:10079600087C008B057E00ED2AFAEE3CFC0ABA00C6
|
||||
:1007A600010C907FC9E0FD7E00C3EA9DEC64808E5B
|
||||
:1007B600F063F08095F04002D322EB042508F5089B
|
||||
:1007C600C32275080075090010000280FB907F9611
|
||||
:1007D600E0FA547FF0C202200207120584920280DA
|
||||
:1007E600F6907F96E0FA4480F0E509600B907FB9B9
|
||||
:0F07F600E509F010010280FB907FC9E4F080C399
|
||||
:0900D000750A00750B00750C00A7
|
||||
:10080500E582FA24C0F582E4347DF583E0F50EEA4D
|
||||
:100815000424C0F582E4347DF583E0F50F74022AE3
|
||||
:10082500FD24C0F582E4347DF583E0C4540FFE5306
|
||||
:10083500060FED24C0F582E4347DF583E0FD740FE9
|
||||
:100845005DF51074032A24C0F582E4347DF583E058
|
||||
:10085500FF74042A24C0F582E4347DF583E0F511A4
|
||||
:10086500EE60078F228E82120C5B907F97E0FE531D
|
||||
:1008750006F87F0074044EF87900AD0E7B001DBDAF
|
||||
:10088500FF011B89027C00C3EA9DEC64808BF06349
|
||||
:10089500F08095F050357A007B00BB080050199028
|
||||
:1008A5007F97EEF0E8F0EAC313FA907F99E0FC3009
|
||||
:1008B500E5034302800B80E2E50D292400F582E47F
|
||||
:1008C500347EF583EAF009890780AF89077A00ABA2
|
||||
:1008D50010751200E512B50F00503EAD0F78001DE2
|
||||
:1008E500BDFF0118A9127C00E9B50511ECB5000D95
|
||||
:1008F500EB600A4306021BE511C313F511907F97C0
|
||||
:10090500EEF074044EF0EAC313FA907F99E0FC30E0
|
||||
:10091500E503430280051280BBAC0F7D007408C35C
|
||||
:100925009CFCE49DFD8CF005F0EA8002C313D5F034
|
||||
:10093500FBFAE50D2F2400F582E4347EF583EAF019
|
||||
:10094500EB60088511228B82020C5B22E582FA247A
|
||||
:10095500C0F582E4347DF583E0F513EA0424C0F59F
|
||||
:1009650082E4347DF583E0F51474022AFD24C0F594
|
||||
:1009750082E4347DF583E0C4540FFE53060FED2465
|
||||
:10098500C0F582E4347DF583E0FD740F5DF51574E3
|
||||
:10099500032A24C0F582E4347DF583E0FF74042A3C
|
||||
:1009A50024C0F582E4347DF583E0F516EE600B8F07
|
||||
:1009B500228E82C002120C5BD002907F97E0FE531C
|
||||
:1009C50006F97F00A9137D0019B9FF011D8F037872
|
||||
:1009D50000C3EB99E864808DF063F08095F05038A2
|
||||
:1009E500EA2F240524C0F582E4347DF583E0FB7D00
|
||||
:1009F50000BD0800501FEB30E0054306018003539E
|
||||
:100A050006FE907F97EEF0EBC313FB907F9774047F
|
||||
:100A15004EF00D80DC0F80ACEA2F240524C0F58252
|
||||
:100A2500E4347DF583E0FBAA157D00EDB514005097
|
||||
:100A350041EB30E00543060180035306FEAF147811
|
||||
:100A4500001FBFFF01188D017C00E9B50711ECB54A
|
||||
:100A5500000DEA600A4306021AE516C313F516905F
|
||||
:100A65007F97EEF0EBC313FB907F9774044EF00D68
|
||||
:100A750080B9EA60088516228A82020C5B22E5822B
|
||||
:100A8500F51824C0F582E4347DF583E0F519E51801
|
||||
:100A95000424C0F582E4347DF583E0F51A7402255B
|
||||
:100AA50018FD24C0F582E4347DF583E0C4540FFEBF
|
||||
:100AB50053060FED24C0F582E4347DF583E0FD7423
|
||||
:100AC5000F5DF51B7403251824C0F582E4347DF50C
|
||||
:100AD50083E0FF7404251824C0F582E4347DF58392
|
||||
:100AE500E0F51CEE60078F228E82120C5B907F97DB
|
||||
:100AF500E0FE5306F97F007900AD197B001DBDFFAF
|
||||
:100B0500011B89007A00C3E89DEA64808BF063F0DD
|
||||
:100B15008095F0505EE51829240524C0F582E4345B
|
||||
:100B25007DF583E0F51D7B007D00BD08005031E5B6
|
||||
:100B35001D30E00543060180035306FE907F97EEC6
|
||||
:100B4500F0E51DC313F51D907F9774044EF0EBC3BC
|
||||
:100B550013FB907F99E0F830E5034303800D80CACD
|
||||
:100B6500E517292400F582E4347EF583EBF0098945
|
||||
:100B75000780868907E51829240524C0F582E43411
|
||||
:100B85007DF583E0F51D7B00AD1B751E00E51EB5EB
|
||||
:100B95001A005054E51D30E0054306018003530655
|
||||
:100BA500FEA91A7C0019B9FF011CA81E7A00E8B538
|
||||
:100BB5000111EAB5040DED600A4306021DE51CC3EB
|
||||
:100BC50013F51C907F97EEF0E51DC313F51D907F7F
|
||||
:100BD5009774044EF0EBC313FB907F99E0FA30E570
|
||||
:100BE50003430380051E80A5AC1A7A007408C39CD4
|
||||
:100BF500FCE49AFA8CF005F0EB8002C313D5F0FB08
|
||||
:100C0500FBE5172F2400F582E4347EF583EBF0ED48
|
||||
:100C15006008851C228D82020C5B22AA82AB837C34
|
||||
:100C2500007D00C3EC9AED9B502B907F97E054FB21
|
||||
:100C3500F07E00EEB50B0050030E80F7907F97E035
|
||||
:100C45004404F07E00EEB50B0050030E80F70CBC9B
|
||||
:100C550000D10D80CE22AA82907F97E0FB74FB5BCA
|
||||
:100C6500F5237B00EBB502005024E52230E0054377
|
||||
:100C7500230280035323FD907F97E523F0E522C3EC
|
||||
:100C850013F522907F9774044523F00B80D622221A
|
||||
:100C95007A00907F99E0FB30E5027A01907F99E038
|
||||
:100CA500FB30E603430202907F9AE0FB30E7034303
|
||||
:100CB5000204907F9BE0FB30E503430208907F9A96
|
||||
:100CC500E0FB53037F8A04E4FAFDEB4AF582ED4C21
|
||||
:100CD500F58322E582547FF4FA907F97E05AF07409
|
||||
:100CE5007F5522FA907F97E04AF02285820A852275
|
||||
:100CF5000B85230C2200227A567B021ABAFF011BB0
|
||||
:100D0500EA4B70F722752205752300120D67AA823A
|
||||
:100D1500AB837C007D00C3EC9AED9B501AC002C0EA
|
||||
:100D250003C004C005120CFAD005D004D003D002CC
|
||||
:100D35000CBC00E20D80DF22AA82AB837C007D0023
|
||||
:100D4500C3EC9AED9B501AC002C003C004C0051243
|
||||
:100D55000CFCD005D004D003D0020CBC00E20D8001
|
||||
:020D6500DF228B
|
||||
:03004300021B009D
|
||||
:101B000002011F0002016E0002016F00020170005D
|
||||
:101B100002017100020172000201730002017400EF
|
||||
:101B200002017500020176000201770002018F00B8
|
||||
:101B30000201A7000201A8000201A9000201AA00F7
|
||||
:101B40000201AB000201AC000201AD000201AE00D7
|
||||
:081B50000201AF000201B00028
|
||||
:100D67007A10E4FBFCE58225E0F582E58333F58321
|
||||
:100D7700EB33FBEC33FCEB9522F5F0EC95234006C7
|
||||
:090D8700FCABF0438201DADD222D
|
||||
:0600A200E478FFF6D8FD32
|
||||
:100080007900E94400601B7A00900E3E780075927A
|
||||
:1000900020E493F2A308B800020592D9F4DAF275CD
|
||||
:0200A00092FFCD
|
||||
:1000A8007800E84400600A7900759220E4F309D8E2
|
||||
:1000B800FC7800E84400600C7900902000E4F0A38C
|
||||
:0400C800D8FCD9FA8D
|
||||
:0D007300758123120DACE582600302006E62
|
||||
:100D900020F71430F6148883A88220F507E6A8838C
|
||||
:100DA00075830022E280F7E49322E022758200221C
|
||||
:00000001FF
|
Loading…
Reference in New Issue