From 9c91ce8d24d0789a0f25affb73201c9e0a6b89d8 Mon Sep 17 00:00:00 2001 From: Ahmed BOUDJELIDA Date: Fri, 16 Jun 2023 23:19:05 +0200 Subject: [PATCH] contrib/firmware: add new adapter ANGIE's firmware/bitstream code This is ANGIE's firmware and bitstream code. The 'Embeded C' code is based on the openULINK project. The hdl bitstream source code is for the spartan-6 FPGA included in ANGIE. Since ANGIE has a different microcontroller (EZ-USB FX2) than openULINK (EZ-USB AN2131), the registers file (reg_ezusb.h) has been changed completely, so are the descriptors, interruptions and the endpoints configuration. Change-Id: I70590c7c58bac6f1939c5ffba57e87d86850664d Signed-off-by: Ahmed BOUDJELIDA Reviewed-on: https://review.openocd.org/c/openocd/+/7701 Tested-by: jenkins Reviewed-by: Antonio Borneo --- contrib/firmware/angie/c/Makefile | 75 ++ contrib/firmware/angie/c/README | 37 + contrib/firmware/angie/c/include/delay.h | 50 ++ contrib/firmware/angie/c/include/fx2macros.h | 31 + contrib/firmware/angie/c/include/io.h | 65 ++ contrib/firmware/angie/c/include/jtag.h | 31 + contrib/firmware/angie/c/include/msgtypes.h | 171 ++++ contrib/firmware/angie/c/include/protocol.h | 20 + contrib/firmware/angie/c/include/reg_ezusb.h | 656 +++++++++++++++ contrib/firmware/angie/c/include/serial.h | 47 ++ contrib/firmware/angie/c/include/usb.h | 273 ++++++ contrib/firmware/angie/c/src/USBJmpTb.a51 | 125 +++ contrib/firmware/angie/c/src/delay.c | 49 ++ contrib/firmware/angie/c/src/gpif.c | 98 +++ contrib/firmware/angie/c/src/jtag.c | 674 +++++++++++++++ contrib/firmware/angie/c/src/main.c | 85 ++ contrib/firmware/angie/c/src/protocol.c | 189 +++++ contrib/firmware/angie/c/src/serial.c | 77 ++ contrib/firmware/angie/c/src/usb.c | 784 ++++++++++++++++++ contrib/firmware/angie/hdl/Makefile | 109 +++ contrib/firmware/angie/hdl/README | 18 + contrib/firmware/angie/hdl/set_env.sh | 14 + .../firmware/angie/hdl/src/angie_openocd.ucf | 35 + .../firmware/angie/hdl/src/angie_openocd.vhd | 66 ++ doc/usb_adapters/angie/584e_424e_angie.txt | 68 ++ 25 files changed, 3847 insertions(+) create mode 100644 contrib/firmware/angie/c/Makefile create mode 100644 contrib/firmware/angie/c/README create mode 100644 contrib/firmware/angie/c/include/delay.h create mode 100644 contrib/firmware/angie/c/include/fx2macros.h create mode 100644 contrib/firmware/angie/c/include/io.h create mode 100644 contrib/firmware/angie/c/include/jtag.h create mode 100644 contrib/firmware/angie/c/include/msgtypes.h create mode 100644 contrib/firmware/angie/c/include/protocol.h create mode 100644 contrib/firmware/angie/c/include/reg_ezusb.h create mode 100644 contrib/firmware/angie/c/include/serial.h create mode 100644 contrib/firmware/angie/c/include/usb.h create mode 100644 contrib/firmware/angie/c/src/USBJmpTb.a51 create mode 100644 contrib/firmware/angie/c/src/delay.c create mode 100644 contrib/firmware/angie/c/src/gpif.c create mode 100644 contrib/firmware/angie/c/src/jtag.c create mode 100644 contrib/firmware/angie/c/src/main.c create mode 100644 contrib/firmware/angie/c/src/protocol.c create mode 100644 contrib/firmware/angie/c/src/serial.c create mode 100644 contrib/firmware/angie/c/src/usb.c create mode 100644 contrib/firmware/angie/hdl/Makefile create mode 100644 contrib/firmware/angie/hdl/README create mode 100644 contrib/firmware/angie/hdl/set_env.sh create mode 100644 contrib/firmware/angie/hdl/src/angie_openocd.ucf create mode 100644 contrib/firmware/angie/hdl/src/angie_openocd.vhd create mode 100644 doc/usb_adapters/angie/584e_424e_angie.txt diff --git a/contrib/firmware/angie/c/Makefile b/contrib/firmware/angie/c/Makefile new file mode 100644 index 0000000000..80e8cbe57b --- /dev/null +++ b/contrib/firmware/angie/c/Makefile @@ -0,0 +1,75 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +#**************************************************************************** +# File : Makefile * +# Contents : Code for NanoXplore USB-JTAG ANGIE adapter hardware. * +# Based on openULINK project by: Martin Schmoelzer. * +# Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. * +# * +# * +# ***************************************************************************/ + +# Define the name of tools. +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 = 0x3C00 +XRAM_LOC = 0x3C00 +XRAM_SIZE = 0x0400 + +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 serial.rel gpif.rel +HEADERS = $(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)/serial.h \ + $(INCLUDE_DIR)/fx2macros.h \ + $(INCLUDE_DIR)/msgtypes.h + +# Disable all built-in rules. +.SUFFIXES: + +# Targets which are executed even when identically named file is present. +.PHONY: all, clean + +all: angie_firmware.ihx + $(SIZE) angie_firmware.ihx + +angie_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 *.lk *.map *.mem + +bin: angie_firmware.ihx + makebin -p angie_firmware.ihx angie_firmware.bin diff --git a/contrib/firmware/angie/c/README b/contrib/firmware/angie/c/README new file mode 100644 index 0000000000..04ed0be2ac --- /dev/null +++ b/contrib/firmware/angie/c/README @@ -0,0 +1,37 @@ +#SPDX-License-Identifier: GPL-2.0-or-later + +This is the ANGIE firmware for ANGIE USB-JTAG adapter. + +The main components of ANGIE adapter are: +- Cypress EZ-USB FX2 microcontroller +- Spartan-6 FPGA +- SRAM memory chip +- Pin headers for various JTAG pin assignments + +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 ANGIE directory to compile the firmware. +"make clean" will remove all generated files except the Intel HEX file +required for downloading the firmware to ANGIE. + +Note that the EZ-USB FX2 microcontroller does not have on-chip flash, +ANGIE include on-board EEPROM memory to store the firmware program of +the FX2, but we are not going to use this method. + +Instead, upon initial connection of the ANGIE adapter to the host PC +via USB, the EZ-USB FX2 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) ANGIE device. + +Once the firmware downloaded, the FX2 microcontroller activate its GPIF mode, +download the Spartan-6 FPGA's bitstream, program the FPGA rapidly, and switch +back to default io mode. + +Once the user disconnects the ANGIE adapter, all its memory contents are lost +and the firmware & bitstream download process has to be executed again. diff --git a/contrib/firmware/angie/c/include/delay.h b/contrib/firmware/angie/c/include/delay.h new file mode 100644 index 0000000000..0397941fe8 --- /dev/null +++ b/contrib/firmware/angie/c/include/delay.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/**************************************************************** + File : delay.h * + Contents : Delays handling header file for NanoXplore * + USB-JTAG ANGIE adapter hardware. * + Based on openULINK project code by: Martin Schmoelzer. * + Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. * + * + * +*****************************************************************/ + +#ifndef __DELAY_H +#define __DELAY_H + +#include + +void syncdelay(uint8_t count); +void delay_5us(void); +void delay_1ms(void); +void delay_us(uint16_t delay); +void delay_ms(uint16_t delay); + +#ifndef _IFREQ +#define _IFREQ 48000 /* IFCLK frequency in kHz */ +#endif + +/* CFREQ can be any one of: 48000, 24000, or 12000 */ +#ifndef _CFREQ +#define _CFREQ 48000 /* CLKOUT frequency in kHz */ +#endif + +#if (_IFREQ < 5000) +#error "_IFREQ too small! Valid Range: 5000 to 48000..." +#endif + +#if (_IFREQ > 48000) +#error "_IFREQ too large! Valid Range: 5000 to 48000..." +#endif + +#if (_CFREQ != 48000) +#if (_CFREQ != 24000) +#if (_CFREQ != 12000) +#error "_CFREQ invalid! Valid values: 48000, 24000, 12000..." +#endif +#endif +#endif + +/* Synchronization Delay formula: see TRM section 15-14 */ +#define _SCYCL (3 * (_CFREQ) + 5 * (_IFREQ) - 1) / (2 * (_IFREQ)) +#endif diff --git a/contrib/firmware/angie/c/include/fx2macros.h b/contrib/firmware/angie/c/include/fx2macros.h new file mode 100644 index 0000000000..9067b56193 --- /dev/null +++ b/contrib/firmware/angie/c/include/fx2macros.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +/* + * This code was taken from the fx2lib project from this link: + * https://github.com/djmuhlestein/fx2lib + * + * Copyright (C) 2009 Ubixum, Inc. +*/ + +/*! \file + * Macros for simple common tasks in fx2 firmware. + * */ + +#ifndef FX2MACROS_H +#define FX2MACROS_H + +#include "reg_ezusb.h" + +typedef enum {FALSE = 0, TRUE} BOOL_VALS; + +/** + * \brief Used for getting and setting the CPU clock speed. + **/ +typedef enum {CLK_12M = 0, CLK_24M, CLK_48M} CLK_SPD; + +/** + * \brief Evaluates to a CLK_SPD enum. + **/ +#define CPUFREQ (CLK_SPD)((CPUCS & bmclkspd) >> 3) + +#endif diff --git a/contrib/firmware/angie/c/include/io.h b/contrib/firmware/angie/c/include/io.h new file mode 100644 index 0000000000..35afa626f7 --- /dev/null +++ b/contrib/firmware/angie/c/include/io.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/**************************************************************************** + File : io.h * + Contents : input/output declaration header file for NanoXplore * + USB-JTAG ANGIE adapter hardware. * + Based on openULINK project code by: Martin Schmoelzer. * + Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. * + * + * +*****************************************************************************/ + +#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 * + * SRST ..... Chip Reset * + ***************************************************************************/ + +/* PORT A */ +/* PA0 Not Connected */ +/* PA1 Not Connected */ +#define PIN_RDWR_B IOA2 +#define PIN_CSI_B IOA3 +#define PIN_INIT_B IOA4 +#define PIN_PROGRAM_B IOA5 +/* PA6 Not Connected */ +/* PA7 Not Connected */ + +/* PORT B */ +#define PIN_TRST IOB0 +#define PIN_TMS IOB1 +#define PIN_TCK IOB2 +#define PIN_TDI IOB3 +#define PIN_TDO IOB4 +#define PIN_SRST IOB5 +/* PA6 Not Connected */ +/* PA7 Not Connected */ + +/* JTAG Signals with direction 'OUT' on port B */ +/* PIN_TDI - PIN_TCK - PIN_TMS - PIN_TRST - PIN_SRST */ +#define MASK_PORTB_DIRECTION_OUT (bmbit0 | bmbit1 | bmbit2 | bmbit3 | bmbit5) + +/* PORT C */ // Debug: +#define PIN_T0 IOC0 +#define PIN_T1 IOC1 +#define PIN_T2 IOC2 +#define PIN_T3 IOC3 +#define PIN_T4 IOC4 +/* PC5 Not Connected */ +/* PC6 Not Connected */ +/* PC7 Not Connected */ + +#endif diff --git a/contrib/firmware/angie/c/include/jtag.h b/contrib/firmware/angie/c/include/jtag.h new file mode 100644 index 0000000000..6d5df64805 --- /dev/null +++ b/contrib/firmware/angie/c/include/jtag.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/**************************************************************************** + File : jtag.h * + Contents : Jtag handling functions header file for NanoXplore * + USB-JTAG ANGIE adapter hardware. * + Based on openULINK project code by: Martin Schmoelzer. * + Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. * + * + * +*****************************************************************************/ + +#ifndef __JTAG_H +#define __JTAG_H + +#include + +uint16_t jtag_get_signals(void); +void jtag_configure_tck_delay(uint8_t scan_in, uint8_t scan_out, + uint8_t scan_io, uint8_t tck, uint8_t tms); +void jtag_clock_tms(uint8_t count, uint8_t sequence); +void jtag_slow_clock_tms(uint8_t count, uint8_t sequence); +void jtag_set_signals(uint8_t low, uint8_t high); +void jtag_clock_tck(uint16_t count); +void jtag_slow_clock_tck(uint16_t count); +void jtag_scan_in(uint8_t out_offset, uint8_t in_offset); +void jtag_scan_out(uint8_t out_offset); +void jtag_scan_io(uint8_t out_offset, uint8_t in_offset); +void jtag_slow_scan_in(uint8_t out_offset, uint8_t in_offset); +void jtag_slow_scan_out(uint8_t out_offset); +void jtag_slow_scan_io(uint8_t out_offset, uint8_t in_offset); +#endif diff --git a/contrib/firmware/angie/c/include/msgtypes.h b/contrib/firmware/angie/c/include/msgtypes.h new file mode 100644 index 0000000000..91116904ad --- /dev/null +++ b/contrib/firmware/angie/c/include/msgtypes.h @@ -0,0 +1,171 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/**************************************************************************** + File : msgtypes.h * + Contents : Definition of the commands supported by NanoXplore * + USB-JTAG ANGIE adapter hardware. * + Based on openULINK project code by: Martin Schmoelzer. * + Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. * + * + * +*****************************************************************************/ + +/** + * @file + * Definition of the commands supported by the ANGIE 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, CMD_SLOW_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_in function * + * offset 2: delay value for scan_out function * + * offset 3: delay value for scan_io function * + * offset 4: delay value for clock_tck function * + * offset 5: 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_SLOW_CLOCK_TCK 0x23 +#define CMD_SLEEP_US 0x24 +#define CMD_SLEEP_MS 0x25 +#define CMD_GET_SIGNALS 0x26 +#define CMD_SET_SIGNALS 0x27 +#define CMD_CONFIGURE_TCK_FREQ 0x28 +#define CMD_SET_LEDS 0x29 +#define CMD_TEST 0x2A + +/* JTAG signal definition for jtag_get_signals() -- Input signals! */ +#define SIGNAL_TDO 1 + +/* JTAG signal definition for jtag_get_signals() -- Output signals! */ +#define SIGNAL_TDI 8 +#define SIGNAL_TMS 2 +#define SIGNAL_TCK 4 +#define SIGNAL_TRST 1 +#define SIGNAL_SRST 32 + +#endif diff --git a/contrib/firmware/angie/c/include/protocol.h b/contrib/firmware/angie/c/include/protocol.h new file mode 100644 index 0000000000..a12644b27d --- /dev/null +++ b/contrib/firmware/angie/c/include/protocol.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/**************************************************************************** + File : protocol.h * + Contents : Jtag commands handling protocol header file for NanoXplore * + USB-JTAG ANGIE adapter hardware. * + Based on openULINK project code by: Martin Schmoelzer. * + Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. * + * + * +*****************************************************************************/ + +#ifndef __PROTOCOL_H +#define __PROTOCOL_H + +#include + +bool execute_command(void); +void command_loop(void); + +#endif diff --git a/contrib/firmware/angie/c/include/reg_ezusb.h b/contrib/firmware/angie/c/include/reg_ezusb.h new file mode 100644 index 0000000000..c22476a1a6 --- /dev/null +++ b/contrib/firmware/angie/c/include/reg_ezusb.h @@ -0,0 +1,656 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/**************************************************************************** + File : reg_ezusb.h * + Contents : FX2 microcontroller registers file for NanoXplore * + USB-JTAG ANGIE adapter hardware. * + Based on openULINK project code by: Martin Schmoelzer. * + Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. * + * + * +*****************************************************************************/ + +#ifndef REG_EZUSB_H +#define REG_EZUSB_H + +/** + * @file + * All information in this file was taken from the EZ-USB FX2 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 FX2 TRM" hereafter. + */ + +/* Compiler-specific definitions of SBIT, SFR, SFRX, ... macros */ +#include + +/* 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 ********************** + ***************************************************************************/ +SFR(IOA, 0x80); +SBIT(IOA0, 0x80, 0); +SBIT(IOA1, 0x80, 1); +SBIT(IOA2, 0x80, 2); +SBIT(IOA3, 0x80, 3); +SBIT(IOA4, 0x80, 4); +SBIT(IOA5, 0x80, 5); +SBIT(IOA6, 0x80, 6); +SBIT(IOA7, 0x80, 7); + +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); +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, 0x8F); +#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(IOB, 0x90); +SBIT(IOB0, 0x90, 0); +SBIT(IOB1, 0x90, 1); +SBIT(IOB2, 0x90, 2); +SBIT(IOB3, 0x90, 3); +SBIT(IOB4, 0x90, 4); +SBIT(IOB5, 0x90, 5); +SBIT(IOB6, 0x90, 6); +SBIT(IOB7, 0x90, 7); + +SFR(EXIF, 0x91); +SBIT(USBINT, 0x91, 4); +SBIT(I2CINT, 0x91, 5); +SBIT(IE4, 0x91, 6); +SBIT(IE5, 0x91, 7); + +SFR(MPAGE, 0x92); +SFR(SCON0, 0x98); +SBIT(RI, 0x98, 0); +SBIT(TI, 0x98, 1); +SBIT(RB8, 0x98, 2); +SBIT(TB8, 0x98, 3); +SBIT(REN, 0x98, 4); +SBIT(SM2, 0x98, 5); +SBIT(SM1, 0x98, 6); +SBIT(SM0, 0x98, 7); + +SFR(SBUF0, 0x99); +SFR(AUTOPTRH1, 0x9A); +SFR(AUTOPTRL1, 0x9B); +SFR(AUTOPTRH2, 0x9D); +SFR(AUTOPTRL2, 0x9E); + +#define AUTOPTR1H AUTOPTRH1 /* for backwards compatibility with examples */ +#define AUTOPTR1L AUTOPTRL1 /* for backwards compatibility with examples */ +#define APTR1H AUTOPTRH1 /* for backwards compatibility with examples */ +#define APTR1L AUTOPTRL1 /* for backwards compatibility with examples */ + +SFR(IOC, 0xA0); +SBIT(IOC0, 0xA0, 0); +SBIT(IOC1, 0xA0, 1); +SBIT(IOC2, 0xA0, 2); +SBIT(IOC3, 0xA0, 3); +SBIT(IOC4, 0xA0, 4); +SBIT(IOC5, 0xA0, 5); +SBIT(IOC6, 0xA0, 6); +SBIT(IOC7, 0xA0, 7); + +SFR(INT2CLR, 0xA1); +SFR(INT4CLR, 0xA2); +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(EP2468STAT, 0xAA); +#define EP8F bmbit7 +#define EP8E bmbit6 +#define EP6F bmbit5 +#define EP6E bmbit4 +#define EP4F bmbit3 +#define EP4E bmbit2 +#define EP2F bmbit1 +#define EP2E bmbit0 + +SFR(EP24FIFOFLGS, 0xAB); +SFR(EP68FIFOFLGS, 0xAC); +SFR(AUTOPTRSETUP, 0xAF); +SFR(IOD, 0xB0); +SBIT(IOD0, 0xB0, 0); +SBIT(IOD1, 0xB0, 1); +SBIT(IOD2, 0xB0, 2); +SBIT(IOD3, 0xB0, 3); +SBIT(IOD4, 0xB0, 4); +SBIT(IOD5, 0xB0, 5); +SBIT(IOD6, 0xB0, 6); +SBIT(IOD7, 0xB0, 7); + +SFR(IOE, 0xB1); +SFR(OEA, 0xB2); +SFR(OEB, 0xB3); +SFR(OEC, 0xB4); +SFR(OED, 0xB5); +SFR(OEE, 0xB6); + +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(EP01STAT, 0xBA); +SFR(GPIFTRIG, 0xBB); +#define BMGPIFDONE bmbit7 +#define BMGPIFREAD bmbit2 +#define GPIF_EP2 0 +#define GPIF_EP4 1 +#define GPIF_EP6 2 +#define GPIF_EP8 3 + +SFR(GPIFSGLDATH, 0xBD); +SFR(GPIFSGLDATLX, 0xBE); +SFR(GPIFSGLDATLNOX, 0xBF); + +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(C_T2, 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 **************************** + ***************************************************************************/ + +SFRX(GPIF_WAVE_DATA, 0xE400); +SFRX(RES_WAVEDATA_END, 0xE480); + +/* General Configuration */ +SFRX(CPUCS, 0xE600); +#define RES8051 bmbit0 +#define CLKOE bmbit1 +#define BMCLKINV bmbit2 +#define bmclkspd0 bmbit3 +#define bmclkspd1 bmbit4 +#define bmclkspd (bmbit4 | bmbit3) +#define BMPRTCSTB bmbit5 + +/* PCON register */ +#define BMSMOD0 bmbit7 + +SFRX(IFCONFIG, 0xE601); +#define BMIFCLKSRC bmbit7 +#define BM3048MHZ bmbit6 +#define BMIFCLKOE bmbit5 +#define BMIFCLKPOL bmbit4 +#define BMASYNC bmbit3 +#define BMGSTATE bmbit2 +#define BMIFCFG1 bmbit1 +#define BMIFCFG0 bmbit0 +#define BMIFCFGMASK (BMIFCFG0 | BMIFCFG1) +#define BMIFGPIF BMIFCFG1 + +SFRX(PINFLAGSAB, 0xE602); +SFRX(PINFLAGSCD, 0xE603); +SFRX(FIFORESET, 0xE604); +#define BMNAKALL bmbit7 + +SFRX(BREAKPT, 0xE605); +#define BMBREAK bmbit3 +#define BMBPPULSE bmbit2 +#define BMBPEN bmbit1 + +SFRX(BPADDRH, 0xE606); +SFRX(BPADDRL, 0xE607); +SFRX(UART230, 0xE608); +SFRX(FIFOPINPOLAR, 0xE609); +SFRX(REVID, 0xE60A); +SFRX(REVCTL, 0xE60B); +#define BMNOAUTOARM bmbit1 +#define BMSKIPCOMMIT bmbit0 + +/* Endpoint Configuration */ +SFRX(EP1OUTCFG, 0xE610); +SFRX(EP1INCFG, 0xE611); +SFRX(EP2CFG, 0xE612); +SFRX(EP4CFG, 0xE613); +SFRX(EP6CFG, 0xE614); +SFRX(EP8CFG, 0xE615); +SFRX(EP2FIFOCFG, 0xE618); +SFRX(EP4FIFOCFG, 0xE619); +SFRX(EP6FIFOCFG, 0xE61A); +SFRX(EP8FIFOCFG, 0xE61B); +#define BMINFM bmbit6 +#define BMOEP bmbit5 +#define BMAUTOOUT bmbit4 +#define BMAUTOIN bmbit3 +#define BMZEROLENIN bmbit2 +#define BMWORDWIDE bmbit0 + +SFRX(EP2AUTOINLENH, 0xE620); +SFRX(EP2AUTOINLENL, 0xE621); +SFRX(EP4AUTOINLENH, 0xE622); +SFRX(EP4AUTOINLENL, 0xE623); +SFRX(EP6AUTOINLENH, 0xE612); +SFRX(EP6AUTOINLENL, 0xE613); +SFRX(EP8AUTOINLENH, 0xE614); +SFRX(EP8AUTOINLENL, 0xE615); +SFRX(EP2FIFOPFH, 0xE630); +SFRX(EP2FIFOPFL, 0xE631); +SFRX(EP4FIFOPFH, 0xE632); +SFRX(EP4FIFOPFL, 0xE633); +SFRX(EP6FIFOPFH, 0xE634); +SFRX(EP6FIFOPFL, 0xE635); +SFRX(EP8FIFOPFH, 0xE636); +SFRX(EP8FIFOPFL, 0xE637); +SFRX(EP2ISOINPKTS, 0xE640); +SFRX(EP4ISOINPKTS, 0xE641); +SFRX(EP6ISOINPKTS, 0xE642); +SFRX(EP8ISOINPKTS, 0xE643); +SFRX(INPKTEND, 0xE648); +SFRX(OUTPKTEND, 0xE649); + +/* Interrupts */ +SFRX(EP2FIFOIE, 0xE650); +SFRX(EP2FIFOIRQ, 0xE651); +SFRX(EP4FIFOIE, 0xE652); +SFRX(EP4FIFOIRQ, 0xE653); +SFRX(EP6FIFOIE, 0xE654); +SFRX(EP6FIFOIRQ, 0xE655); +SFRX(EP8FIFOIE, 0xE656); +SFRX(EP8FIFOIRQ, 0xE657); +SFRX(IBNIE, 0xE658); +SFRX(IBNIRQ, 0xE659); +#define EP0IBN bmbit0 +#define EP1IBN bmbit1 +#define EP2IBN bmbit2 +#define EP4IBN bmbit3 +#define EP6IBN bmbit4 +#define EP8IBN bmbit5 + +SFRX(NAKIE, 0xE65A); +SFRX(NAKIRQ, 0xE65B); +#define EP8PING bmbit7 +#define EP6PING bmbit6 +#define EP4PING bmbit5 +#define EP2PING bmbit4 +#define EP1PING bmbit3 +#define EP0PING bmbit2 +#define IBN bmbit0 + +SFRX(USBIEN, 0xE65C); +SFRX(USBIRQ, 0xE65D); +#define SUDAVI bmbit0 +#define SOFI bmbit1 +#define SUTOKI bmbit2 +#define SUSPI bmbit3 +#define URESI bmbit4 +#define HSGRANT bmbit5 +#define EP0ACK bmbit6 + +SFRX(EPIE, 0xE65E); +SFRX(EPIRQ, 0xE65F); +SFRX(GPIFIE, 0xE660); +SFRX(GPIFIRQ, 0xE661); +SFRX(USBERRIE, 0xE662); +SFRX(USBERRIRQ, 0xE663); +SFRX(ERRCNTLIM, 0xE664); +SFRX(CLRERRCNT, 0xE665); +SFRX(INT2IVEC, 0xE666); +#define I2V0 bmbit2 +#define I2V1 bmbit3 +#define I2V2 bmbit4 +#define I2V3 bmbit5 +#define I2V4 bmbit6 + +SFRX(INT4IVEC, 0xE667); +SFRX(INTSETUP, 0xE668); +#define AV4EN bmbit0 +#define INT4IN bmbit1 +#define AV2EN bmbit3 + +/* Input/Output */ +SFRX(PORTACFG, 0xE670); +#define BMINT0 bmbit0 +#define BMINT1 bmbit1 +#define BMFLAGD bmbit7 + +SFRX(PORTCCFG, 0xE671); +#define BMGPIFA0 bmbit0 +#define BMGPIFA1 bmbit1 +#define BMGPIFA2 bmbit2 +#define BMGPIFA3 bmbit3 +#define BMGPIFA4 bmbit4 +#define BMGPIFA5 bmbit5 +#define BMGPIFA6 bmbit6 +#define BMGPIFA7 bmbit7 + +SFRX(PORTECFG, 0xE672); +#define BMT0OUT bmbit0 +#define BMT1OUT bmbit1 +#define BMT2OUT bmbit2 +#define BMRXD0OUT bmbit3 +#define BMRXD1OUT bmbit4 +#define BMINT6 bmbit5 +#define BMT2EX bmbit6 +#define BMGPIFA8 bmbit7 + +SFRX(I2CS, 0xE678); +#define BMDONE bmbit0 +#define BMACK bmbit1 +#define BMBERR bmbit2 +#define BMID (bmbit4 | bmbit3) +#define BMLASTRD bmbit5 +#define BMSTOP bmbit6 +#define BMSTART bmbit7 + +SFRX(I2DAT, 0xE679); +SFRX(I2CTL, 0xE67A); +#define BMSTOPIE bmbit1 +#define BM400KHZ bmbit0 + +SFRX(XAUTODAT1, 0xE67B); +SFRX(XAUTODAT2, 0xE67C); +#define EXTAUTODAT1 XAUTODAT1 +#define EXTAUTODAT2 XAUTODAT2 + +/* USB Control */ +SFRX(USBCS, 0xE680); +#define SIGRSUME bmbit0 +#define RENUM bmbit1 +#define NOSYNSOF bmbit2 +#define DISCON bmbit3 +#define HSM bmbit7 + +SFRX(SUSPEND, 0xE681); +SFRX(WAKEUPCS, 0xE682); +#define BMWU2 bmbit7 +#define BMWU bmbit6 +#define BMWU2POL bmbit5 +#define BMWUPOL bmbit4 +#define BMDPEN bmbit2 +#define BMWU2EN bmbit1 +#define BMWUEN bmbit0 + +SFRX(TOGCTL, 0xE683); +#define BMTOGCTLEPMASK bmbit3 | bmbit2 | bmbit1 | bmbit0 +#define BMRESETTOGGLE bmbit5 +#define BMSETTOGGLE bmbit6 +#define BMQUERYTOGGLE bmbit7 + +SFRX(USBFRAMEH, 0xE684); +SFRX(USBFRAMEL, 0xE685); +SFRX(MICROFRAME, 0xE686); +SFRX(FNADDR, 0xE687); + +/* Endpoints */ +SFRX(EP0BCH, 0xE68A); +SFRX(EP0BCL, 0xE68B); +SFRX(EP1OUTBC, 0xE68D); +SFRX(EP1INBC, 0xE68F); +SFRX(EP2BCH, 0xE690); +SFRX(EP2BCL, 0xE691); +SFRX(EP4BCH, 0xE694); +SFRX(EP4BCL, 0xE695); +SFRX(EP6BCH, 0xE698); +SFRX(EP6BCL, 0xE699); +SFRX(EP8BCH, 0xE69C); +SFRX(EP8BCL, 0xE69D); +SFRX(EP0CS, 0xE6A0); +#define HSNAK bmbit7 + +SFRX(EP1INCS, 0xE6A2); +SFRX(EP1OUTCS, 0xE6A1); +#define EPSTALL bmbit0 +#define EPBSY bmbit1 + +SFRX(EP2CS, 0xE6A3); +SFRX(EP4CS, 0xE6A4); +SFRX(EP6CS, 0xE6A5); +SFRX(EP8CS, 0xE6A6); +#define BMEPEMPTY bmbit2 +#define BMEPFULL bmbit3 +#define BMNPAK (bmbit6 | bmbit5 | bmbit4) + +SFRX(EP2FIFOFLGS, 0xE6A7); +SFRX(EP4FIFOFLGS, 0xE6A8); +SFRX(EP6FIFOFLGS, 0xE6A9); +SFRX(EP8FIFOFLGS, 0xE6AA); +SFRX(EP2FIFOBCH, 0xE6AB); +SFRX(EP2FIFOBCL, 0xE6AC); +SFRX(EP4FIFOBCH, 0xE6AD); +SFRX(EP4FIFOBCL, 0xE6AE); +SFRX(EP6FIFOBCH, 0xE6AF); +SFRX(EP6FIFOBCL, 0xE6B0); +SFRX(EP8FIFOBCH, 0xE6B1); +SFRX(EP8FIFOBCL, 0xE6B2); +SFRX(SUDPTRH, 0xE6B3); +SFRX(SUDPTRL, 0xE6B4); + +SFRX(SUDPTRCTL, 0xE6B5); +#define BMSDPAUTO bmbit0 + +SFRX(SETUPDAT[8], 0xE6B8); + +/* GPIF */ +SFRX(GPIFWFSELECT, 0xE6C0); +SFRX(GPIFIDLECS, 0xE6C1); +SFRX(GPIFIDLECTL, 0xE6C2); +SFRX(GPIFCTLCFG, 0xE6C3); +SFRX(GPIFADRH, 0xE6C4); +SFRX(GPIFADRL, 0xE6C5); +SFRX(GPIFTCB3, 0xE6CE); +SFRX(GPIFTCB2, 0xE6CF); +SFRX(GPIFTCB1, 0xE6D0); +SFRX(GPIFTCB0, 0xE6D1); + +#define EP2GPIFTCH GPIFTCB1 /* these are here for backwards compatibility */ +#define EP2GPIFTCL GPIFTCB0 +#define EP4GPIFTCH GPIFTCB1 /* these are here for backwards compatibility */ +#define EP4GPIFTCL GPIFTCB0 +#define EP6GPIFTCH GPIFTCB1 /* these are here for backwards compatibility */ +#define EP6GPIFTCL GPIFTCB0 +#define EP8GPIFTCH GPIFTCB1 /* these are here for backwards compatibility */ +#define EP8GPIFTCL GPIFTCB0 + +SFRX(EP2GPIFFLGSEL, 0xE6D2); +SFRX(EP2GPIFPFSTOP, 0xE6D3); +SFRX(EP2GPIFTRIG, 0xE6D4); +SFRX(EP4GPIFFLGSEL, 0xE6DA); +SFRX(EP4GPIFPFSTOP, 0xE6DB); +SFRX(EP4GPIFTRIG, 0xE6DC); +SFRX(EP6GPIFFLGSEL, 0xE6E2); +SFRX(EP6GPIFPFSTOP, 0xE6E3); +SFRX(EP6GPIFTRIG, 0xE6E4); +SFRX(EP8GPIFFLGSEL, 0xE6EA); +SFRX(EP8GPIFPFSTOP, 0xE6EB); +SFRX(EP8GPIFTRIG, 0xE6EC); +SFRX(XGPIFSGLDATH, 0xE6F0); +SFRX(XGPIFSGLDATLX, 0xE6F1); +SFRX(XGPIFSGLDATLNOX, 0xE6F2); +SFRX(GPIFREADYCFG, 0xE6F3); +SFRX(GPIFREADYSTAT, 0xE6F4); +SFRX(GPIFABORT, 0xE6F5); + +// UDMA +SFRX(FLOWSTATE, 0xE6C6); +SFRX(FLOWLOGIC, 0xE6C7); +SFRX(FLOWEQ0CTL, 0xE6C8); +SFRX(FLOWEQ1CTL, 0xE6C9); +SFRX(FLOWHOLDOFF, 0xE6CA); +SFRX(FLOWSTB, 0xE6CB); +SFRX(FLOWSTBEDGE, 0xE6CC); +SFRX(FLOWSTBHPERIOD, 0xE6CD); +SFRX(GPIFHOLDAMOUNT, 0xE60C); +SFRX(UDMACRCH, 0xE67D); +SFRX(UDMACRCL, 0xE67E); +SFRX(UDMACRCQUAL, 0xE67F); + +/* Debug/Test + * The following registers are for Cypress's internal testing purposes only. + * These registers are not documented in the datasheet or the Technical Reference + * Manual as they were not designed for end user application usage + */ +SFRX(DBUG, 0xE6F8); +SFRX(TESTCFG, 0xE6F9); +SFRX(USBTEST, 0xE6FA); +SFRX(CT1, 0xE6FB); +SFRX(CT2, 0xE6FC); +SFRX(CT3, 0xE6FD); +SFRX(CT4, 0xE6FE); + +/* Endpoint Buffers */ +SFRX(EP0BUF[64], 0xE740); +SFRX(EP1INBUF[64], 0xE7C0); +SFRX(EP1OUTBUF[64], 0xE780); +SFRX(EP2FIFOBUF[512], 0xF000); +SFRX(EP4FIFOBUF[512], 0xF400); +SFRX(EP6FIFOBUF[512], 0xF800); +SFRX(EP8FIFOBUF[512], 0xFC00); + +/* Error Correction Code (ECC) Registers (FX2LP/FX1 only) */ +SFRX(ECCCFG, 0xE628); +SFRX(ECCRESET, 0xE629); +SFRX(ECC1B0, 0xE62A); +SFRX(ECC1B1, 0xE62B); +SFRX(ECC1B2, 0xE62C); +SFRX(ECC2B0, 0xE62D); +SFRX(ECC2B1, 0xE62E); +SFRX(ECC2B2, 0xE62F); + +/* Feature Registers (FX2LP/FX1 only) */ +SFRX(GPCR2, 0xE50D); +#define BMFULLSPEEDONLY bmbit4 + +#endif diff --git a/contrib/firmware/angie/c/include/serial.h b/contrib/firmware/angie/c/include/serial.h new file mode 100644 index 0000000000..548c005603 --- /dev/null +++ b/contrib/firmware/angie/c/include/serial.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +/** + * This code was taken from the fx2lib project from this link: + * https://github.com/djmuhlestein/fx2lib + * + * Copyright (C) 2009 Ubixum, Inc. + **/ + +/** \file serial.h + * defines functions to print to a serial console with SIO0 + **/ + +#include "fx2macros.h" +#include +/** + * This function inits sio0 to use T2CON (timer 2) + * See TRM 14.3.4.1 (Table 14-16) + * Certain baud rates have too high an error rate to work. All baud rates are .16% + * except: + * + * 12MHZ 24MHZ + * \li 57600 -6.99% + * \li 38400 -2.34% -2.34% + * \li 19200 -2.34% + * + * Possible Baud rates: + * \li 2400 + * \li 4800 + * \li 9600 + * \li 19200 + * \li 28800 + * \li 38400 + * \li 57600 + * + * Any of these rates should work except 57600 at 12mhz. -2.34% is pushing + * most hardware specs for working. All rates at 48mhz work at .16% + **/ + +void sio0_init(uint32_t baud_rate) __critical; /* baud_rate max should be 57600 since int=2 bytes */ + +/** + * putchar('\\n') or putchar('\\r') both transmit \\r\\n + * Just use one or the other. (This makes terminal echo easy) + **/ +int putchar(char c); +int getchar(void); diff --git a/contrib/firmware/angie/c/include/usb.h b/contrib/firmware/angie/c/include/usb.h new file mode 100644 index 0000000000..0450d1d1c9 --- /dev/null +++ b/contrib/firmware/angie/c/include/usb.h @@ -0,0 +1,273 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/**************************************************************************** + File : usb.h * + Contents : usb communication handling header file for NanoXplore * + USB-JTAG ANGIE adapter hardware. * + Based on openULINK project code by: Martin Schmoelzer. * + Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. * + * + * +*****************************************************************************/ + +#ifndef __USB_H +#define __USB_H + +#include "reg_ezusb.h" +#include +#include + +/* High and Low byte of a word (uint16_t) */ +#define HI8(word) (uint8_t)(((uint16_t)(word) >> 8) & 0xff) +#define LO8(word) (uint8_t)((uint16_t)(word) & 0xff) + +/* Convenience functions */ +#define STALL_EP0() (EP0CS |= EPSTALL) +#define CLEAR_IRQ() (USBINT = 0) + +/*********** 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 */ +struct usb_device_descriptor { + uint8_t blength; /**< Size of this descriptor in bytes. */ + uint8_t bdescriptortype; /**< DEVICE Descriptor Type. */ + uint16_t bcdusb; /**< USB specification release number (BCD). */ + uint8_t bdeviceclass; /**< Class code. */ + uint8_t bdevicesubclass; /**< Subclass code. */ + uint8_t bdeviceprotocol; /**< Protocol code. */ + uint8_t bmaxpacketsize0; /**< Maximum packet size for EP0 (8, 16, 32, 64). */ + uint16_t idvendor; /**< USB Vendor ID. */ + uint16_t idproduct; /**< USB Product ID. */ + uint16_t bcddevice; /**< Device Release Number (BCD). */ + uint8_t imanufacturer; /**< Index of manufacturer string descriptor. */ + uint8_t iproduct; /**< Index of product string descriptor. */ + uint8_t iserialnumber; /**< Index of string descriptor containing serial #. */ + uint8_t bnumconfigurations; /**< Number of possible configurations. */ +}; + +/** USB Configuration Descriptor. See USB 1.1 spec, pp. 199 - 200 */ +struct usb_config_descriptor { + uint8_t blength; /**< Size of this descriptor in bytes. */ + uint8_t bdescriptortype; /**< CONFIGURATION descriptor type. */ + uint16_t wtotallength; /**< Combined total length of all descriptors. */ + uint8_t bnuminterfaces; /**< Number of interfaces in this configuration. */ + uint8_t bconfigurationvalue; /**< Value used to select this configuration. */ + uint8_t iconfiguration; /**< Index of configuration string descriptor. */ + uint8_t bmattributes; /**< Configuration characteristics. */ + uint8_t maxpower; /**< Maximum power consumption in 2 mA units. */ +}; + +/** USB Interface Descriptor. See USB 1.1 spec, pp. 201 - 203 */ +struct usb_interface_descriptor { + uint8_t blength; /**< Size of this descriptor in bytes. */ + uint8_t bdescriptortype; /**< INTERFACE descriptor type. */ + uint8_t binterfacenumber; /**< Interface number. */ + uint8_t balternatesetting; /**< Value used to select alternate setting. */ + uint8_t bnumendpoints; /**< Number of endpoints used by this interface. */ + uint8_t binterfaceclass; /**< Class code. */ + uint8_t binterfacesubclass; /**< Subclass code. */ + uint8_t binterfaceprotocol; /**< Protocol code. */ + uint8_t iinterface; /**< Index of interface string descriptor. */ +}; + +/** USB Endpoint Descriptor. See USB 1.1 spec, pp. 203 - 204 */ +struct usb_endpoint_descriptor { + uint8_t blength; /**< Size of this descriptor in bytes. */ + uint8_t bdescriptortype; /**< ENDPOINT descriptor type. */ + uint8_t bendpointaddress; /**< Endpoint Address: IN/OUT + EP number. */ + uint8_t bmattributes; /**< Endpoint Attributes: BULK/INTR/ISO/CTRL. */ + uint16_t wmaxpacketsize; /**< Maximum packet size for this endpoint. */ + uint8_t binterval; /**< Polling interval (in ms) for this endpoint. */ +}; + +/** USB Language Descriptor. See USB 1.1 spec, pp. 204 - 205 */ +struct usb_language_descriptor { + uint8_t blength; /**< Size of this descriptor in bytes. */ + uint8_t bdescriptortype; /**< STRING descriptor type. */ + uint16_t wlangid[]; /**< LANGID codes. */ +}; + +/** USB String Descriptor. See USB 1.1 spec, pp. 204 - 205 */ +struct usb_string_descriptor { + uint8_t blength; /**< Size of this descriptor in bytes. */ + uint8_t bdescriptortype; /**< STRING descriptor type. */ + uint16_t bstring[]; /**< UNICODE encoded string. */ +}; + +/********************** USB Control Endpoint 0 related *********************/ + +/** USB Control Setup Data. See USB 1.1 spec, pp. 183 - 185 */ +struct setup_data { + uint8_t bmrequesttype; /**< Characteristics of a request. */ + uint8_t brequest; /**< Specific request. */ + uint16_t wvalue; /**< Field that varies according to request. */ + uint16_t windex; /**< Field that varies according to request. */ + uint16_t wlength; /**< Number of bytes to transfer in data stage. */ +}; + +/* External declarations for variables that need to be accessed outside of + * the USB module */ +extern volatile bool ep1_out; +extern volatile bool ep1_in; + +extern volatile __xdata __at 0xE6B8 struct setup_data 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 + +/* 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 */ +enum usb_isr { + SUDAV_ISR = 13, + SOF_ISR, + SUTOK_ISR, + SUSPEND_ISR, + USBRESET_ISR, + HIGHSPEED_ISR, + EP0ACK_ISR, + STUB_ISR, + EP0IN_ISR, + EP0OUT_ISR, + EP1IN_ISR, + EP1OUT_ISR, + EP2_ISR, + EP4_ISR, + EP6_ISR, + EP8_ISR, + IBN_ISR, + EP0PINGNAK_ISR, + EP1PINGNAK_ISR, + EP2PINGNAK_ISR, + EP4PINGNAK_ISR, + EP6PINGNAK_ISR, + EP8PINGNAK_ISR, + ERRORLIMIT_ISR, + EP2PIDERROR_ISR, + EP4PIDERROR_ISR, + EP6PIDERROR_ISR, + EP8PIDERROR_ISR, + EP2PFLAG_ISR, + EP4PFLAG_ISR, + EP6PFLAG_ISR, + EP8PFLAG_ISR, + EP2EFLAG_ISR, + EP4EFLAG_ISR, + EP6EFLAG_ISR, + EP8EFLAG_ISR, + EP2FFLAG_ISR, + EP4FFLAG_ISR, + EP6FFLAG_ISR, + EP8FFLAG_ISR, + GPIFCOMPLETE_ISR, + GPIFWAVEFORM_ISR +}; + +/*************************** Function Prototypes ***************************/ +__xdata uint8_t *usb_get_endpoint_cs_reg(uint8_t ep); +void usb_reset_data_toggle(uint8_t 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 ep_init(void); +void interrupt_init(void); +void io_init(void); + +#endif diff --git a/contrib/firmware/angie/c/src/USBJmpTb.a51 b/contrib/firmware/angie/c/src/USBJmpTb.a51 new file mode 100644 index 0000000000..13b5f7218b --- /dev/null +++ b/contrib/firmware/angie/c/src/USBJmpTb.a51 @@ -0,0 +1,125 @@ +; SPDX-License-Identifier: GPL-2.0-or-later +;**************************************************************************** +; File : USBJmpTb.a51 * +; Contents : Interruptions vector configuration. * +; Based on openULINK project code by: Martin Schmoelzer. * +; Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. * +; * +; * +;**************************************************************************** +.module JUMPTABLE + +.globl USB_AutoVector +.globl USB_Jump_Table + +.globl _sudav_isr, _sof_isr, _sutok_isr, _suspend_isr, _usbreset_isr, _highspeed_isr, _ep0ack_isr, _stub_isr, _ep0in_isr, _ep0out_isr, _ep1in_isr, _ep1out_isr, _ep2_isr, _ep4_isr, _ep6_isr, _ep8_isr, _ibn_isr +.globl _ep0pingnak_isr, _ep1pingnak_isr, _ep2pingnak_isr, _ep4pingnak_isr, _ep6pingnak_isr, _ep8pingnak_isr, _errorlimit_isr, _stub_isr, _stub_isr, _stub_isr, _ep2piderror_isr, _ep4piderror_isr, _ep6piderror_isr, _ep8piderror_isr +.globl _ep2pflag_isr, _ep4pflag_isr, _ep6pflag_isr, _ep8pflag_isr, _ep2eflag_isr, _ep4eflag_isr, _ep6eflag_isr, _ep8eflag_isr, _ep2fflag_isr, _ep4fflag_isr, _ep6fflag_isr, _ep8fflag_isr, _gpifcomplete_isr, _gpifwaveform_isr + +;--------------------------------------------------------------------------; +; Interrupt Vectors ; +;--------------------------------------------------------------------------; +.area USB_JV (ABS,OVR) ; Absolute, Overlay +.org 0x43 ; USB interrupt (INT2) jumps here +USB_AutoVector = #. + 2 + ljmp USB_Jump_Table ; Autovector will replace byte 45 + +;--------------------------------------------------------------------------; +; USB Jump Table ; +;--------------------------------------------------------------------------; +.area USB_JT (ABS) ; Absolute placement +.org 0x0200 ; Place jump table at 0x0200 + +USB_Jump_Table: ; autovector jump table + ljmp _sudav_isr ; (00) Setup Data Available + .db 0 + ljmp _sof_isr ; (04) Start of Frame + .db 0 + ljmp _sutok_isr ; (08) Setup Data Loading + .db 0 + ljmp _suspend_isr ; (0C) Global Suspend + .db 0 + ljmp _usbreset_isr ; (10) USB Reset + .db 0 + ljmp _highspeed_isr ; (14) Entered High Speed + .db 0 + ljmp _ep0ack_isr ; (18) EP0ACK + .db 0 + ljmp _stub_isr ; (1C) Reserved + .db 0 + ljmp _ep0in_isr ; (20) EP0 In + .db 0 + ljmp _ep0out_isr ; (24) EP0 Out + .db 0 + ljmp _ep1in_isr ; (28) EP1 In + .db 0 + ljmp _ep1out_isr ; (2C) EP1 Out + .db 0 + ljmp _ep2_isr ; (30) EP2 In/Out + .db 0 + ljmp _ep4_isr ; (34) EP4 In/Out + .db 0 + ljmp _ep6_isr ; (38) EP6 In/Out + .db 0 + ljmp _ep8_isr ; (3C) EP8 In/Out + .db 0 + ljmp _ibn_isr ; (40) IBN + .db 0 + ljmp _stub_isr ; (44) Reserved + .db 0 + ljmp _ep0pingnak_isr ; (48) EP0 PING NAK + .db 0 + ljmp _ep1pingnak_isr ; (4C) EP1 PING NAK + .db 0 + ljmp _ep2pingnak_isr ; (50) EP2 PING NAK + .db 0 + ljmp _ep4pingnak_isr ; (54) EP4 PING NAK + .db 0 + ljmp _ep6pingnak_isr ; (58) EP6 PING NAK + .db 0 + ljmp _ep8pingnak_isr ; (5C) EP8 PING NAK + .db 0 + ljmp _errorlimit_isr ; (60) Error Limit + .db 0 + ljmp _stub_isr ; (64) Reserved + .db 0 + ljmp _stub_isr ; (68) Reserved + .db 0 + ljmp _stub_isr ; (6C) Reserved + .db 0 + ljmp _ep2piderror_isr ; (70) EP2 ISO Pid Sequence Error + .db 0 + ljmp _ep4piderror_isr ; (74) EP4 ISO Pid Sequence Error + .db 0 + ljmp _ep6piderror_isr ; (78) EP6 ISO Pid Sequence Error + .db 0 + ljmp _ep8piderror_isr ; (7C) EP8 ISO Pid Sequence Error + .db 0 + ljmp _ep2pflag_isr ; (80) EP2 Programmable Flag + .db 0 + ljmp _ep4pflag_isr ; (84) EP4 Programmable Flag + .db 0 + ljmp _ep6pflag_isr ; (88) EP6 Programmable Flag + .db 0 + ljmp _ep8pflag_isr ; (8C) EP8 Programmable Flag + .db 0 + ljmp _ep2eflag_isr ; (90) EP2 Empty Flag + .db 0 + ljmp _ep4eflag_isr ; (94) EP4 Empty Flag + .db 0 + ljmp _ep6eflag_isr ; (98) EP6 Empty Flag + .db 0 + ljmp _ep8eflag_isr ; (9C) EP8 Empty Flag + .db 0 + ljmp _ep2fflag_isr ; (A0) EP2 Full Flag + .db 0 + ljmp _ep4fflag_isr ; (A4) EP4 Full Flag + .db 0 + ljmp _ep6fflag_isr ; (A8) EP6 Full Flag + .db 0 + ljmp _ep8fflag_isr ; (AC) EP8 Full Flag + .db 0 + ljmp _gpifcomplete_isr ; (B0) GPIF Operation Complete + .db 0 + ljmp _gpifwaveform_isr ; (B4) GPIF Waveform + .db 0 diff --git a/contrib/firmware/angie/c/src/delay.c b/contrib/firmware/angie/c/src/delay.c new file mode 100644 index 0000000000..471e160dd4 --- /dev/null +++ b/contrib/firmware/angie/c/src/delay.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/**************************************************************************** + File : delay.c * + Contents : Delays handling fucntions code for NanoXplore * + USB-JTAG ANGIE adapter hardware. * + Based on openULINK project code by: Martin Schmoelzer. * + Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. * + * + * +*****************************************************************************/ + +#include "delay.h" +#include + +void syncdelay(uint8_t count) +{ + for (uint8_t i = 0; i < count; i++) + NOP(); +} + +void delay_5us(void) +{ + NOP(); +} + +void delay_1ms(void) +{ + uint16_t i; + + for (i = 0; i < 598; i++) + ; +} + +void delay_us(uint16_t delay) +{ + uint16_t i; + uint16_t maxcount = (delay / 5); + + for (i = 0; i < maxcount; i++) + delay_5us(); +} + +void delay_ms(uint16_t delay) +{ + uint16_t i; + + for (i = 0; i < delay; i++) + delay_1ms(); +} diff --git a/contrib/firmware/angie/c/src/gpif.c b/contrib/firmware/angie/c/src/gpif.c new file mode 100644 index 0000000000..80a9571087 --- /dev/null +++ b/contrib/firmware/angie/c/src/gpif.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/* + This program configures the General Programmable Interface (GPIF) for FX2. + Please do not modify sections of text which are marked as "DO NOT EDIT ...". +*/ + +/* GPIF Program Code */ + +#include "reg_ezusb.h" +#include "delay.h" + +/****************************** GPIF PROGRAM CODE ********************************/ +/* DO NOT EDIT ... */ +const char wavedata[128] = { +/* Wave 0 */ +/* LenBr */ 0x01, 0x3F, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, +/* Opcode*/ 0x02, 0x07, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, +/* Output*/ 0x04, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, +/* LFun */ 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, +/* Wave 1 */ +/* LenBr */ 0x88, 0x01, 0x3F, 0x01, 0x01, 0x01, 0x01, 0x07, +/* Opcode*/ 0x01, 0x02, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, +/* Output*/ 0x07, 0x05, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, +/* LFun */ 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x3F, +/* Wave 2 */ +/* LenBr */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, +/* Opcode*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* Output*/ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, +/* LFun */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, +/* Wave 3 */ +/* LenBr */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, +/* Opcode*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* Output*/ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, +/* LFun */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, +}; +/* END DO NOT EDIT */ + +/* DO NOT EDIT ... */ +const char flowstates[36] = { +/* Wave 0 flowstates */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* Wave 1 flowstates */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* Wave 2 flowstates */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* Wave 3 flowstates */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +/* END DO NOT EDIT */ + +/* DO NOT EDIT ... */ +const char initdata[7] = { +/* Regs */ 0xE0, 0x00, 0x00, 0x07, 0xEE, 0xF2, 0x00 +}; +/* END DO NOT EDIT */ + +void gpif_init(void) +{ + uint8_t i; + + IFCONFIG = 0xEE; + + GPIFABORT = 0xFF; /* abort any waveforms pending */ + GPIFREADYCFG = initdata[0]; + GPIFCTLCFG = initdata[1]; + GPIFIDLECS = initdata[2]; + GPIFIDLECTL = initdata[3]; + GPIFWFSELECT = initdata[5]; + GPIFREADYSTAT = initdata[6]; + + /* use dual autopointer feature... */ + AUTOPTRSETUP = 0x07; + + /* source */ + AUTOPTRH1 = (uint8_t)(((uint16_t)(&wavedata) >> 8) & 0xff); + AUTOPTRL1 = (uint8_t)((uint16_t)(&wavedata) & 0xff); + + /* destination */ + AUTOPTRH2 = 0xE4; + AUTOPTRL2 = 0x00; + + /* transfer */ + for (i = 0x00; i < 128; i++) + EXTAUTODAT2 = EXTAUTODAT1; + + /* GPIF address pins update when GPIFADRH/L written */ + syncdelay(3); + GPIFADRH = 0x00; /* bits[7:1] always 0 */ + syncdelay(3); + GPIFADRL = 0x00; /* point to PERIPHERAL address 0x0000 */ + + /* Configure GPIF flowstates registers for Wave 0 of wavedata */ + FLOWSTATE = flowstates[0]; + FLOWLOGIC = flowstates[1]; + FLOWEQ0CTL = flowstates[2]; + FLOWEQ1CTL = flowstates[3]; + FLOWHOLDOFF = flowstates[4]; + FLOWSTB = flowstates[5]; + FLOWSTBEDGE = flowstates[6]; + FLOWSTBHPERIOD = flowstates[7]; +} diff --git a/contrib/firmware/angie/c/src/jtag.c b/contrib/firmware/angie/c/src/jtag.c new file mode 100644 index 0000000000..9a44cd0bfc --- /dev/null +++ b/contrib/firmware/angie/c/src/jtag.c @@ -0,0 +1,674 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/**************************************************************************** + File : jtag.c * + Contents : Jtag handling functions code for NanoXplore * + USB-JTAG ANGIE adapter hardware. * + Based on openULINK project code by: Martin Schmoelzer. * + Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. * + * + * +*****************************************************************************/ + +#include "jtag.h" +#include "io.h" +#include "msgtypes.h" +#include "reg_ezusb.h" +#include +#include +#include + +/** Delay value for SCAN_IN operations with less than maximum TCK frequency */ +uint8_t delay_scan_in; + +/** Delay value for SCAN_OUT operations with less than maximum TCK frequency */ +uint8_t delay_scan_out; + +/** Delay value for SCAN_IO operations with less than maximum TCK frequency */ +uint8_t delay_scan_io; + +/** Delay value for CLOCK_TCK operations with less than maximum frequency */ +uint8_t delay_tck; + +/** Delay value for CLOCK_TMS operations with less than maximum frequency */ +uint8_t delay_tms; + +/** + * 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. + * + * Maximum achievable TCK frequency is 182 kHz for ANGIE clocked at 24 MHz. + * + * @param out_offset offset in EP1OUTBUF where payload data starts + * @param in_offset + */ +void jtag_scan_in(uint8_t out_offset, uint8_t in_offset) +{ + uint8_t scan_size_bytes, bits_last_byte; + uint8_t tms_count_start, tms_count_end; + uint8_t tms_sequence_start, tms_sequence_end; + uint8_t tdo_data, i, j; + + uint8_t outb_buffer; + + /* Get parameters from EP1OUTBUF */ + scan_size_bytes = EP1OUTBUF[out_offset]; + bits_last_byte = EP1OUTBUF[out_offset + 1]; + tms_count_start = (EP1OUTBUF[out_offset + 2] >> 4) & 0x0F; + tms_count_end = EP1OUTBUF[out_offset + 2] & 0x0F; + tms_sequence_start = EP1OUTBUF[out_offset + 3]; + tms_sequence_end = EP1OUTBUF[out_offset + 4]; + + if (tms_count_start > 0) + jtag_clock_tms(tms_count_start, tms_sequence_start); + + outb_buffer = IOB & ~(bmbit1 | bmbit2 | bmbit3); + + /* 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++) { + IOB = outb_buffer; /* TCK changes here */ + tdo_data = tdo_data >> 1; + IOB = (outb_buffer | bmbit2); + + if (PIN_TDO) + tdo_data |= 0x80; + } + + /* Copy TDO data to EP1INBUF */ + EP1INBUF[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 |= bmbit1; + tms_count_end--; + tms_sequence_end = tms_sequence_end >> 1; + } + + IOB = outb_buffer; /* TCK changes here */ + tdo_data = tdo_data >> 1; + IOB = (outb_buffer | bmbit2); + + if (PIN_TDO) + tdo_data |= 0x80; + } + tdo_data = tdo_data >> (8 - bits_last_byte); + + /* Copy TDO data to EP1INBUF */ + EP1INBUF[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-IN operation at variable TCK frequency. + * + * Dummy data is shifted into the JTAG chain via TDI, TDO data is sampled and + * stored in the EP2 IN buffer. + * + * Maximum achievable TCK frequency is 113 kHz for ANGIE clocked at 24 MHz. + * + * @param out_offset offset in EP1OUTBUF where payload data starts + * @param in_offset + */ +void jtag_slow_scan_in(uint8_t out_offset, uint8_t in_offset) +{ + uint8_t scan_size_bytes, bits_last_byte; + uint8_t tms_count_start, tms_count_end; + uint8_t tms_sequence_start, tms_sequence_end; + uint8_t tdo_data, i, j, k; + uint8_t outb_buffer; + + /* Get parameters from EP1OUTBUF */ + scan_size_bytes = EP1OUTBUF[out_offset]; + bits_last_byte = EP1OUTBUF[out_offset + 1]; + tms_count_start = (EP1OUTBUF[out_offset + 2] >> 4) & 0x0F; + tms_count_end = EP1OUTBUF[out_offset + 2] & 0x0F; + tms_sequence_start = EP1OUTBUF[out_offset + 3]; + tms_sequence_end = EP1OUTBUF[out_offset + 4]; + + if (tms_count_start > 0) + jtag_slow_clock_tms(tms_count_start, tms_sequence_start); + + outb_buffer = IOB & ~(bmbit3 | bmbit2 | bmbit1); + + /* 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++) { + IOB = outb_buffer; /* TCK changes here */ + for (k = 0; k < delay_scan_in; k++) + ; + tdo_data = tdo_data >> 1; + + IOB = (outb_buffer | bmbit2); + for (k = 0; k < delay_scan_in; k++) + ; + + if (PIN_TDO) + tdo_data |= 0x80; + } + + /* Copy TDO data to EP1INBUF */ + EP1INBUF[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 |= bmbit1; + tms_count_end--; + tms_sequence_end = tms_sequence_end >> 1; + } + + IOB = outb_buffer; /* TCK changes here */ + for (k = 0; k < delay_scan_in; k++) + ; + tdo_data = tdo_data >> 1; + + IOB = (outb_buffer | bmbit2); + for (k = 0; k < delay_scan_in; k++) + ; + + if (PIN_TDO) + tdo_data |= 0x80; + } + tdo_data = tdo_data >> (8 - bits_last_byte); + + /* Copy TDO data to EP1INBUF */ + EP1INBUF[i + in_offset] = tdo_data; + + /* Move to correct end state */ + if (tms_count_end > 0) + jtag_slow_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 always left in the PAUSE-DR/PAUSE-IR state. + * + * Maximum achievable TCK frequency is 142 kHz for ANGIE clocked at 24 MHz. + * + * @param out_offset offset in EP1OUTBUF where payload data starts + */ +void jtag_scan_out(uint8_t out_offset) +{ + uint8_t scan_size_bytes, bits_last_byte; + uint8_t tms_count_start, tms_count_end; + uint8_t tms_sequence_start, tms_sequence_end; + uint8_t tdi_data, i, j; + uint8_t outb_buffer; + + /* Get parameters from EP1OUTBUF */ + scan_size_bytes = EP1OUTBUF[out_offset]; + bits_last_byte = EP1OUTBUF[out_offset + 1]; + tms_count_start = (EP1OUTBUF[out_offset + 2] >> 4) & 0x0F; + tms_count_end = EP1OUTBUF[out_offset + 2] & 0x0F; + tms_sequence_start = EP1OUTBUF[out_offset + 3]; + tms_sequence_end = EP1OUTBUF[out_offset + 4]; + + if (tms_count_start > 0) + jtag_clock_tms(tms_count_start, tms_sequence_start); + outb_buffer = IOB & ~(bmbit2 | bmbit1); + + /* Shift all bytes except the last byte */ + for (i = 0; i < scan_size_bytes - 1; i++) { + tdi_data = EP1OUTBUF[i + out_offset + 5]; + + for (j = 0; j < 8; j++) { + if (tdi_data & 0x01) + outb_buffer |= bmbit3; + else + outb_buffer &= ~bmbit3; + + IOB = outb_buffer; /* TDI and TCK change here */ + tdi_data = tdi_data >> 1; + IOB = (outb_buffer | bmbit2); + } + } + tdi_data = EP1OUTBUF[i + out_offset + 5]; + + /* Shift the last byte */ + for (j = 0; j < bits_last_byte; j++) { + if (tdi_data & 0x01) + outb_buffer |= bmbit3; + else + outb_buffer &= ~bmbit3; + + /* Assert TMS signal if requested and this is the last bit */ + if (j == (bits_last_byte - 1) && tms_count_end > 0) { + outb_buffer |= bmbit1; + tms_count_end--; + tms_sequence_end = tms_sequence_end >> 1; + } + IOB = outb_buffer; /* TDI and TCK change here */ + tdi_data = tdi_data >> 1; + IOB = (outb_buffer | bmbit2); + } + + /* 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 always left in the PAUSE-DR/PAUSE-IR state. + * + * Maximum achievable TCK frequency is 97 kHz for ANGIE clocked at 24 MHz. + * + * @param out_offset offset in EP1OUTBUF where payload data starts + */ +void jtag_slow_scan_out(uint8_t out_offset) +{ + uint8_t scan_size_bytes, bits_last_byte; + uint8_t tms_count_start, tms_count_end; + uint8_t tms_sequence_start, tms_sequence_end; + uint8_t tdi_data, i, j, k; + uint8_t outb_buffer; + + /* Get parameters from EP1OUTBUF */ + scan_size_bytes = EP1OUTBUF[out_offset]; + bits_last_byte = EP1OUTBUF[out_offset + 1]; + tms_count_start = (EP1OUTBUF[out_offset + 2] >> 4) & 0x0F; + tms_count_end = EP1OUTBUF[out_offset + 2] & 0x0F; + tms_sequence_start = EP1OUTBUF[out_offset + 3]; + tms_sequence_end = EP1OUTBUF[out_offset + 4]; + + if (tms_count_start > 0) + jtag_slow_clock_tms(tms_count_start, tms_sequence_start); + outb_buffer = IOB & ~(bmbit2 | bmbit1); + + /* Shift all bytes except the last byte */ + for (i = 0; i < scan_size_bytes - 1; i++) { + tdi_data = EP1OUTBUF[i + out_offset + 5]; + + for (j = 0; j < 8; j++) { + if (tdi_data & 0x01) + outb_buffer |= bmbit3; + else + outb_buffer &= ~bmbit3; + IOB = outb_buffer; /* TDI and TCK change here */ + for (k = 0; k < delay_scan_out; k++) + ; + tdi_data = tdi_data >> 1; + IOB = (outb_buffer | bmbit2); + for (k = 0; k < delay_scan_out; k++) + ; + } + } + tdi_data = EP1OUTBUF[i + out_offset + 5]; + + /* Shift the last byte */ + for (j = 0; j < bits_last_byte; j++) { + if (tdi_data & 0x01) + outb_buffer |= bmbit3; + else + outb_buffer &= ~bmbit3; + + /* Assert TMS signal if requested and this is the last bit */ + if (j == (bits_last_byte - 1) && tms_count_end > 0) { + outb_buffer |= bmbit1; + tms_count_end--; + tms_sequence_end = tms_sequence_end >> 1; + } + IOB = outb_buffer; /* TDI and TCK change here */ + for (k = 0; k < delay_scan_out; k++) + ; + tdi_data = tdi_data >> 1; + IOB = (outb_buffer | bmbit2); + for (k = 0; k < delay_scan_out; k++) + ; + } + + /* Move to correct end state */ + if (tms_count_end > 0) + jtag_slow_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 always left in the PAUSE-DR/PAUSE-IR state. + * + * Maximum achievable TCK frequency is 100 kHz for ANGIE clocked at 24 MHz. + * + * @param out_offset offset in EP1OUTBUF where payload data starts + * @param in_offset + */ +int it; +void jtag_scan_io(uint8_t out_offset, uint8_t in_offset) +{ + uint8_t scan_size_bytes, bits_last_byte; + uint8_t tms_count_start, tms_count_end; + uint8_t tms_sequence_start, tms_sequence_end; + uint8_t tdi_data, tdo_data, i, j; + uint8_t outb_buffer; + + it++; + /* Get parameters from EP1OUTBUF */ + scan_size_bytes = EP1OUTBUF[out_offset]; + bits_last_byte = EP1OUTBUF[out_offset + 1]; + tms_count_start = (EP1OUTBUF[out_offset + 2] >> 4) & 0x0F; + tms_count_end = EP1OUTBUF[out_offset + 2] & 0x0F; + tms_sequence_start = EP1OUTBUF[out_offset + 3]; + tms_sequence_end = EP1OUTBUF[out_offset + 4]; + + if (tms_count_start > 0) + jtag_clock_tms(tms_count_start, tms_sequence_start); + outb_buffer = IOB & ~(bmbit2 | bmbit1); + + /* Shift all bytes except the last byte */ + for (i = 0; i < scan_size_bytes - 1; i++) { + tdi_data = EP1OUTBUF[i + out_offset + 5]; + tdo_data = 0; + for (j = 0; j < 8; j++) { + if (tdi_data & 0x01) + outb_buffer |= bmbit3; + else + outb_buffer &= ~bmbit3; + IOB = outb_buffer; /* TDI and TCK change here */ + tdi_data = tdi_data >> 1; + IOB = (outb_buffer | bmbit2); + tdo_data = tdo_data >> 1; + if (PIN_TDO) + tdo_data |= 0x80; + } + + /* Copy TDO data to EP1INBUF */ + EP1INBUF[i + in_offset] = tdo_data; + } + tdi_data = EP1OUTBUF[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 |= bmbit3; + else + outb_buffer &= ~bmbit3; + + /* Assert TMS signal if requested and this is the last bit */ + if (j == (bits_last_byte - 1) && tms_count_end > 0) { + outb_buffer |= bmbit1; + tms_count_end--; + tms_sequence_end = tms_sequence_end >> 1; + } + IOB = outb_buffer; /* TDI and TCK change here */ + tdi_data = tdi_data >> 1; + IOB = (outb_buffer | bmbit2); + tdo_data = tdo_data >> 1; + if (PIN_TDO) + tdo_data |= 0x80; + } + tdo_data = tdo_data >> (8 - bits_last_byte); + + /* Copy TDO data to EP1INBUF */ + EP1INBUF[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 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 always left in the PAUSE-DR/PAUSE-IR state. + * + * Maximum achievable TCK frequency is 78 kHz for ANGIE clocked at 24 MHz. + * + * @param out_offset offset in EP1OUTBUF where payload data starts + * @param in_offset + */ +void jtag_slow_scan_io(uint8_t out_offset, uint8_t in_offset) +{ + uint8_t scan_size_bytes, bits_last_byte; + uint8_t tms_count_start, tms_count_end; + uint8_t tms_sequence_start, tms_sequence_end; + uint8_t tdi_data, tdo_data, i, j, k; + uint8_t outb_buffer; + + /* Get parameters from EP1OUTBUF */ + scan_size_bytes = EP1OUTBUF[out_offset]; + bits_last_byte = EP1OUTBUF[out_offset + 1]; + tms_count_start = (EP1OUTBUF[out_offset + 2] >> 4) & 0x0F; + tms_count_end = EP1OUTBUF[out_offset + 2] & 0x0F; + tms_sequence_start = EP1OUTBUF[out_offset + 3]; + tms_sequence_end = EP1OUTBUF[out_offset + 4]; + + if (tms_count_start > 0) + jtag_slow_clock_tms(tms_count_start, tms_sequence_start); + outb_buffer = IOB & ~(bmbit2 | bmbit1); + + /* Shift all bytes except the last byte */ + for (i = 0; i < scan_size_bytes - 1; i++) { + tdi_data = EP1OUTBUF[i + out_offset + 5]; + tdo_data = 0; + for (j = 0; j < 8; j++) { + if (tdi_data & 0x01) + outb_buffer |= bmbit3; + else + outb_buffer &= ~bmbit3; + IOB = outb_buffer; /* TDI and TCK change here */ + for (k = 0; k < delay_scan_io; k++) + ; + tdi_data = tdi_data >> 1; + IOB = (outb_buffer | bmbit2); + for (k = 0; k < delay_scan_io; k++) + ; + tdo_data = tdo_data >> 1; + if (PIN_TDO) + tdo_data |= 0x80; + } + + /* Copy TDO data to EP1INBUF */ + EP1INBUF[i + in_offset] = tdo_data; + } + tdi_data = EP1OUTBUF[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 |= bmbit3; + else + outb_buffer &= ~bmbit3; + + /* Assert TMS signal if requested and this is the last bit */ + if (j == (bits_last_byte - 1) && tms_count_end > 0) { + outb_buffer |= bmbit1; + tms_count_end--; + tms_sequence_end = tms_sequence_end >> 1; + } + IOB = outb_buffer; /* TDI and TCK change here */ + for (k = 0; k < delay_scan_io; k++) + ; + tdi_data = tdi_data >> 1; + IOB = (outb_buffer | bmbit2); + for (k = 0; k < delay_scan_io; k++) + ; + tdo_data = tdo_data >> 1; + if (PIN_TDO) + tdo_data |= 0x80; + } + tdo_data = tdo_data >> (8 - bits_last_byte); + + /* Copy TDO data to EP1INBUF */ + EP1INBUF[i + in_offset] = tdo_data; + + /* Move to correct end state */ + if (tms_count_end > 0) + jtag_slow_clock_tms(tms_count_end, tms_sequence_end); +} + +/** + * Generate TCK clock cycles. + * + * Maximum achievable TCK frequency is 375 kHz for ANGIE clocked at 24 MHz. + * + * @param count number of TCK clock cycles to generate. + */ +void jtag_clock_tck(uint16_t count) +{ + uint16_t i; + uint8_t outb_buffer = IOB & ~(bmbit2); + + for (i = 0; i < count; i++) { + IOB = outb_buffer; + IOB = outb_buffer | bmbit2; + } +} + +/** + * Generate TCK clock cycles at variable frequency. + * + * Maximum achievable TCK frequency is 166.6 kHz for ANGIE clocked at 24 MHz. + * + * @param count number of TCK clock cycles to generate. + */ +void jtag_slow_clock_tck(uint16_t count) +{ + uint16_t i; + uint8_t j; + uint8_t outb_buffer = IOB & ~(bmbit2); + + for (i = 0; i < count; i++) { + IOB = outb_buffer; + for (j = 0; j < delay_tck; j++) + ; + IOB = outb_buffer | bmbit2; + for (j = 0; j < delay_tck; j++) + ; + } +} + +/** + * Perform TAP FSM state transitions at maximum TCK frequency. + * + * Maximum achievable TCK frequency is 176 kHz for ANGIE clocked at 24 MHz. + * + * @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(uint8_t count, uint8_t sequence) +{ + uint8_t outb_buffer = IOB & ~(bmbit2); + uint8_t i; + + for (i = 0; i < count; i++) { + /* Set TMS pin according to sequence parameter */ + if (sequence & 0x1) + outb_buffer |= bmbit1; + else + outb_buffer &= ~bmbit1; + IOB = outb_buffer; + sequence = sequence >> 1; + IOB = outb_buffer | bmbit2; + } +} + +/** + * Perform TAP-FSM state transitions at less than maximum TCK frequency. + * + * Maximum achievable TCK frequency is 117 kHz for ANGIE clocked at 24 MHz. + * + * @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(uint8_t count, uint8_t sequence) +{ + uint8_t outb_buffer = IOB & ~(bmbit2); + uint8_t i, j; + + for (i = 0; i < count; i++) { + /* Set TMS pin according to sequence parameter */ + if (sequence & 0x1) + outb_buffer |= bmbit1; + else + outb_buffer &= ~bmbit1; + IOB = outb_buffer; + for (j = 0; j < delay_tms; j++) + ; + sequence = sequence >> 1; + IOB = outb_buffer | bmbit2; + for (j = 0; j < delay_tms; j++) + ; + } +} + +uint16_t jtag_get_signals(void) +{ + uint8_t input_signal_state, output_signal_state; + input_signal_state = 0; + output_signal_state = 0; + + /* Get states of input pins */ + if (PIN_TDO) + input_signal_state |= SIGNAL_TDO; + + /* Get states of output pins */ + output_signal_state = IOB & MASK_PORTB_DIRECTION_OUT; + + return ((uint16_t)input_signal_state << 8) | ((uint16_t)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(uint8_t low, uint8_t high) +{ + IOB &= ~(low & MASK_PORTB_DIRECTION_OUT); + IOB |= (high & MASK_PORTB_DIRECTION_OUT); +} + +/** + * Configure TCK delay parameters. + * + * @param scan_in number of delay cycles in scan_in operations. + * @param scan_out number of delay cycles in scan_out operations. + * @param scan_io number of delay cycles in scan_io 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(uint8_t scan_in, uint8_t scan_out, + uint8_t scan_io, uint8_t tck, uint8_t tms) +{ + delay_scan_in = scan_in; + delay_scan_out = scan_out; + delay_scan_io = scan_io; + delay_tck = tck; + delay_tms = tms; +} diff --git a/contrib/firmware/angie/c/src/main.c b/contrib/firmware/angie/c/src/main.c new file mode 100644 index 0000000000..9290af2ab5 --- /dev/null +++ b/contrib/firmware/angie/c/src/main.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/**************************************************************************** + File : main.c * + Contents : main code for NanoXplore USB-JTAG ANGIE adapter * + hardware. * + Based on openULINK project code by: Martin Schmoelzer. * + Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. * + * + * +*****************************************************************************/ + +#include "usb.h" +#include "delay.h" +#include "protocol.h" +#include "reg_ezusb.h" +#include +#include + +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 highspeed_isr(void)__interrupt; +extern void ep0ack_isr(void)__interrupt; +extern void stub_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 ep2_isr(void)__interrupt; +extern void ep4_isr(void)__interrupt; +extern void ep6_isr(void)__interrupt; +extern void ep8_isr(void)__interrupt; +extern void ibn_isr(void)__interrupt; +extern void ep0pingnak_isr(void)__interrupt; +extern void ep1pingnak_isr(void)__interrupt; +extern void ep2pingnak_isr(void)__interrupt; +extern void ep4pingnak_isr(void)__interrupt; +extern void ep6pingnak_isr(void)__interrupt; +extern void ep8pingnak_isr(void)__interrupt; +extern void errorlimit_isr(void)__interrupt; +extern void ep2piderror_isr(void)__interrupt; +extern void ep4piderror_isr(void)__interrupt; +extern void ep6piderror_isr(void)__interrupt; +extern void ep8piderror_isr(void)__interrupt; +extern void ep2pflag_isr(void)__interrupt; +extern void ep4pflag_isr(void)__interrupt; +extern void ep6pflag_isr(void)__interrupt; +extern void ep8pflag_isr(void)__interrupt; +extern void ep2eflag_isr(void)__interrupt; +extern void ep4eflag_isr(void)__interrupt; +extern void ep6eflag_isr(void)__interrupt; +extern void ep8eflag_isr(void)__interrupt; +extern void ep2fflag_isr(void)__interrupt; +extern void ep4fflag_isr(void)__interrupt; +extern void ep6fflag_isr(void)__interrupt; +extern void ep8fflag_isr(void)__interrupt; +extern void gpifcomplete_isr(void)__interrupt; +extern void gpifwaveform_isr(void)__interrupt; + +void gpif_init(void); + +int main(void) +{ + CPUCS = ((CPUCS & ~bmclkspd) | (CLK_48M << 3) | CLKOE); /* required for sio0_init */ + sio0_init(57600); /* needed for printf */ + + ep_init(); + gpif_init(); + interrupt_init(); + io_init(); + + /* Perform ReNumeration */ + USBCS |= (DISCON | RENUM); + delay_ms(250); + USBCS &= ~DISCON; + + /* Begin executing command(s). This function never returns. */ + command_loop(); + + /* Never reached, but SDCC complains about missing return statement */ + return 0; +} diff --git a/contrib/firmware/angie/c/src/protocol.c b/contrib/firmware/angie/c/src/protocol.c new file mode 100644 index 0000000000..3f3aaaf362 --- /dev/null +++ b/contrib/firmware/angie/c/src/protocol.c @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/**************************************************************************** + File : protocol.c * + Contents : Jtag commands handling protocol code for NanoXplore * + USB-JTAG ANGIE adapter hardware. * + Based on openULINK project code by: Martin Schmoelzer. * + Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. * + * + * +*****************************************************************************/ + +#include "usb.h" +#include "protocol.h" +#include "jtag.h" +#include "delay.h" +#include "io.h" +#include "msgtypes.h" +#include "reg_ezusb.h" +#include +#include + +/** Index in EP1 Bulk-OUT data buffer that contains the current command ID */ +volatile uint8_t cmd_id_index; + +/** Number of data bytes already in EP1 Bulk-IN buffer */ +volatile uint8_t payload_index_in; + +/** + * Executes one command and updates global command indexes. + * + * @return true if this command was the last command. + * @return false if there are more commands within the current contents of the + * Bulk EP1-OUT data buffer. + */ +bool execute_command(void) +{ + uint8_t usb_out_bytecount, usb_in_bytecount; + uint16_t signal_state = 0; + uint16_t 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 + * necessary */ + usb_in_bytecount = 0; + + switch (EP1OUTBUF[cmd_id_index] /* Command ID */) { + case CMD_SCAN_IN: + usb_out_bytecount = 5; + usb_in_bytecount = EP1OUTBUF[cmd_id_index + 1]; + jtag_scan_in((cmd_id_index + 1), payload_index_in); + break; + case CMD_SCAN_OUT: + usb_out_bytecount = EP1OUTBUF[cmd_id_index + 1] + 5; + jtag_scan_out(cmd_id_index + 1); + break; + case CMD_SCAN_IO: + usb_in_bytecount = EP1OUTBUF[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(EP1OUTBUF[cmd_id_index + 1], EP1OUTBUF[cmd_id_index + 2]); + break; + case CMD_CLOCK_TCK: + usb_out_bytecount = 2; + count = (uint16_t)EP1OUTBUF[cmd_id_index + 1]; + count |= ((uint16_t)EP1OUTBUF[cmd_id_index + 2]) << 8; + jtag_clock_tck(count); + break; + case CMD_SLOW_SCAN_IN: + usb_out_bytecount = 5; + usb_in_bytecount = EP1OUTBUF[cmd_id_index + 1]; + jtag_slow_scan_in(cmd_id_index + 1, payload_index_in); + break; + case CMD_SLOW_SCAN_OUT: + usb_out_bytecount = EP1OUTBUF[cmd_id_index + 1] + 5; + jtag_slow_scan_out(cmd_id_index + 1); + break; + case CMD_SLOW_SCAN_IO: + usb_in_bytecount = EP1OUTBUF[cmd_id_index + 1]; + usb_out_bytecount = usb_in_bytecount + 5; + jtag_slow_scan_io(cmd_id_index + 1, payload_index_in); + break; + case CMD_SLOW_CLOCK_TMS: + usb_out_bytecount = 2; + jtag_slow_clock_tms(EP1OUTBUF[cmd_id_index + 1], EP1OUTBUF[cmd_id_index + 2]); + break; + case CMD_SLOW_CLOCK_TCK: + usb_out_bytecount = 2; + count = (uint16_t)EP1OUTBUF[cmd_id_index + 1]; + count |= ((uint16_t)EP1OUTBUF[cmd_id_index + 2]) << 8; + jtag_slow_clock_tck(count); + break; + case CMD_SLEEP_US: + usb_out_bytecount = 2; + count = (uint16_t)EP1OUTBUF[cmd_id_index + 1]; + count |= ((uint16_t)EP1OUTBUF[cmd_id_index + 2]) << 8; + delay_us(count); + break; + case CMD_SLEEP_MS: + usb_out_bytecount = 2; + count = (uint16_t)EP1OUTBUF[cmd_id_index + 1]; + count |= ((uint16_t)EP1OUTBUF[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(); + EP1INBUF[payload_index_in] = (signal_state >> 8); + EP1INBUF[payload_index_in + 1] = (signal_state & 0xFF); + break; + case CMD_SET_SIGNALS: + usb_out_bytecount = 2; + jtag_set_signals(EP1OUTBUF[cmd_id_index + 1], EP1OUTBUF[cmd_id_index + 2]); + break; + case CMD_CONFIGURE_TCK_FREQ: + usb_out_bytecount = 5; + jtag_configure_tck_delay(EP1OUTBUF[cmd_id_index + 1], /* scan_in */ + EP1OUTBUF[cmd_id_index + 2], /* scan_out */ + EP1OUTBUF[cmd_id_index + 3], /* scan_io */ + EP1OUTBUF[cmd_id_index + 4], /* clock_tck */ + EP1OUTBUF[cmd_id_index + 5]); /* clock_tms */ + 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 EP1 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) >= EP1OUTBC) { + return true; + /* Line between return and else required by checkpatch: */ + uint8_t a = 0; + } 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 EP1 Bulk-OUT packet */ + while (!ep1_out) + ; + ep1_out = false; + + /* Execute the commands */ + last_command = false; + while (!last_command) + last_command = execute_command(); + + /* Send back EP6 Bulk-IN packet if required */ + if (payload_index_in > 0) { + EP1INBC = payload_index_in; + syncdelay(3); + + while (!ep1_in) + ; + ep1_in = false; + } + + /* Re-arm EP1-OUT after command execution */ + EP1OUTBC = 0; + syncdelay(3); + EP1OUTBC = 0; + syncdelay(3); + } +} diff --git a/contrib/firmware/angie/c/src/serial.c b/contrib/firmware/angie/c/src/serial.c new file mode 100644 index 0000000000..0398cb23cf --- /dev/null +++ b/contrib/firmware/angie/c/src/serial.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +/* + * This code was taken from the fx2lib project from this link: + * https://github.com/djmuhlestein/fx2lib + * + * Copyright (C) 2009 Ubixum, Inc. +*/ + +#include +#include +#include +#include +/** + * using the comp port implies that timer 2 will be used as + * a baud rate generator. (Don't use timer 2) + **/ +void sio0_init(uint32_t baud_rate) __critical +{ + uint16_t hl; /* hl value for reload */ + uint8_t mult; /* multiplier for clock speed */ + uint32_t tmp; /* scratch for mult/divide */ + + mult = (CPUFREQ == CLK_12M) ? 1 : ((CPUFREQ == CLK_24M) ? 2 : 4); + + /* set the clock rate */ + /* use clock 2 */ + RCLK = 1; TCLK = 1; + tmp = mult * 375000L * 2; + tmp /= baud_rate; + tmp += 1; + tmp /= 2; + hl = 0xFFFF - (uint16_t)tmp; + RCAP2H = (uint8_t)(((uint16_t)(hl) >> 8) & 0xff); + + /* seems that the 24/48mhz calculations are always one less than suggested values */ + /* trm table 14-16 */ + RCAP2L = ((uint8_t)((uint16_t)(hl) & 0xff)) + (mult > 0 ? 1 : 0); + + /* start the timer */ + TR2 = 1; + + /* set up the serial port */ + SM0 = 0; SM1 = 1; /* serial mode 1 (asyncronous) */ + SM2 = 0 ; /* has to do with receiving */ + REN = 1 ; /* to enable receiving */ + PCON |= 0x80; /* SET SMOD0, baud rate doubler */ + TI = 1; /* we send initial byte */ +} + +int getchar(void) +{ + char c; + while (!RI) + ; + c = SBUF0; + RI = 0; + return c; +} + +void _transchar(char c) +{ + while (!TI) + ; /* wait for TI=1 */ + TI = 0; + SBUF0 = c; +} + +int putchar (char c) +{ + if (c == '\n') + _transchar('\r'); /* transmit \r\n */ + _transchar(c); + if (c == '\r') + _transchar('\n'); /* transmit \r\n */ + return c; +} diff --git a/contrib/firmware/angie/c/src/usb.c b/contrib/firmware/angie/c/src/usb.c new file mode 100644 index 0000000000..8fd4de6373 --- /dev/null +++ b/contrib/firmware/angie/c/src/usb.c @@ -0,0 +1,784 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/**************************************************************************** + File : usb.c * + Contents : usb communication handling code for NanoXplore USB-JTAG * + ANGIE adapter hardware. * + Based on openULINK project code by: Martin Schmoelzer. * + Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. * + * + * +*****************************************************************************/ + +#include "usb.h" +#include "stdint.h" +#include "delay.h" +#include "io.h" +#include "reg_ezusb.h" +#include +#include +#include + +/* Also update external declarations in "include/usb.h" if making changes to + * these variables! + */ +volatile bool ep1_out; +volatile bool ep1_in; + +volatile __xdata __at 0xE6B8 struct setup_data setup_data; + +/* Define number of endpoints (except Control Endpoint 0) in a central place. + * Be sure to include the necessary endpoint descriptors! + */ +#define NUM_ENDPOINTS 3 + +__code struct usb_device_descriptor device_descriptor = { + .blength = sizeof(struct usb_device_descriptor), + .bdescriptortype = DESCRIPTOR_TYPE_DEVICE, + .bcdusb = 0x0200, /* BCD: 02.00 (Version 2.0 USB spec) */ + .bdeviceclass = 0xFF, /* 0xFF = vendor-specific */ + .bdevicesubclass = 0xFF, + .bdeviceprotocol = 0xFF, + .bmaxpacketsize0 = 64, + .idvendor = 0x584e, + .idproduct = 0x424e, + .bcddevice = 0x0000, + .imanufacturer = 1, + .iproduct = 2, + .iserialnumber = 3, + .bnumconfigurations = 1 +}; + +/* WARNING: ALL config, interface and endpoint descriptors MUST be adjacent! */ + +__code struct usb_config_descriptor config_descriptor = { + .blength = sizeof(struct usb_config_descriptor), + .bdescriptortype = DESCRIPTOR_TYPE_CONFIGURATION, + .wtotallength = sizeof(struct usb_config_descriptor) + + sizeof(struct usb_interface_descriptor) + + (NUM_ENDPOINTS * sizeof(struct usb_endpoint_descriptor)), + .bnuminterfaces = 1, + .bconfigurationvalue = 1, + .iconfiguration = 4, /* String describing this configuration */ + .bmattributes = 0x80, /* Only MSB set according to USB spec */ + .maxpower = 50 /* 100 mA */ +}; + +__code struct usb_interface_descriptor interface_descriptor00 = { + .blength = sizeof(struct usb_interface_descriptor), + .bdescriptortype = DESCRIPTOR_TYPE_INTERFACE, + .binterfacenumber = 0, + .balternatesetting = 0, + .bnumendpoints = NUM_ENDPOINTS, + .binterfaceclass = 0xFF, + .binterfacesubclass = 0xFF, + .binterfaceprotocol = 0xFF, + .iinterface = 0 +}; + +__code struct usb_endpoint_descriptor bulk_ep1_out_endpoint_descriptor = { + .blength = sizeof(struct usb_endpoint_descriptor), + .bdescriptortype = 0x05, + .bendpointaddress = (1 | USB_DIR_OUT), + .bmattributes = 0x02, + .wmaxpacketsize = 64, + .binterval = 0 +}; + +__code struct usb_endpoint_descriptor bulk_ep1_in_endpoint_descriptor = { + .blength = sizeof(struct usb_endpoint_descriptor), + .bdescriptortype = 0x05, + .bendpointaddress = (1 | USB_DIR_IN), + .bmattributes = 0x02, + .wmaxpacketsize = 64, + .binterval = 0 +}; + +__code struct usb_endpoint_descriptor bulk_ep2_endpoint_descriptor = { + .blength = sizeof(struct usb_endpoint_descriptor), + .bdescriptortype = 0x05, + .bendpointaddress = (2 | USB_DIR_OUT), + .bmattributes = 0x02, + .wmaxpacketsize = 512, + .binterval = 0 +}; + +__code struct usb_endpoint_descriptor bulk_ep4_endpoint_descriptor = { + .blength = sizeof(struct usb_endpoint_descriptor), + .bdescriptortype = 0x05, + .bendpointaddress = (4 | USB_DIR_IN), + .bmattributes = 0x02, + .wmaxpacketsize = 512, + .binterval = 0 +}; + +__code struct usb_endpoint_descriptor bulk_ep6_endpoint_descriptor = { + .blength = sizeof(struct usb_endpoint_descriptor), + .bdescriptortype = 0x05, + .bendpointaddress = (6 | USB_DIR_OUT), + .bmattributes = 0x02, + .wmaxpacketsize = 512, + .binterval = 0 +}; + +__code struct usb_endpoint_descriptor bulk_ep8_endpoint_descriptor = { + .blength = sizeof(struct usb_endpoint_descriptor), + .bdescriptortype = 0x05, + .bendpointaddress = (8 | USB_DIR_OUT), + .bmattributes = 0x02, + .wmaxpacketsize = 512, + .binterval = 0 +}; + +__code struct usb_language_descriptor language_descriptor = { + .blength = 4, + .bdescriptortype = DESCRIPTOR_TYPE_STRING, + .wlangid = {0x0409 /* US English */} +}; + +__code struct usb_string_descriptor strmanufacturer = + STR_DESCR(16, 'N', 'a', 'n', 'o', 'X', 'p', 'l', 'o', 'r', 'e', ',', ' ', 'S', 'A', 'S', '.'); + +__code struct usb_string_descriptor strproduct = + STR_DESCR(13, 'A', 'N', 'G', 'I', 'E', ' ', 'A', 'd', 'a', 'p', 't', 'e', 'r'); + +__code struct usb_string_descriptor strserialnumber = + STR_DESCR(6, '0', '0', '0', '0', '0', '1'); + +__code struct usb_string_descriptor strconfigdescr = + STR_DESCR(12, 'J', 'T', 'A', 'G', ' ', 'A', 'd', 'a', 'p', 't', 'e', 'r'); + +/* Table containing pointers to string descriptors */ +__code struct usb_string_descriptor *__code en_string_descriptors[4] = { + &strmanufacturer, + &strproduct, + &strserialnumber, + &strconfigdescr +}; +void sudav_isr(void)__interrupt SUDAV_ISR +{ + EXIF &= ~0x10; /* Clear USBINT: Main global interrupt */ + USBIRQ = SUDAVI; + EP0CS |= HSNAK; + usb_handle_setup_data(); +} +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 highspeed_isr(void)__interrupt HIGHSPEED_ISR +{ +} +void ep0ack_isr(void)__interrupt EP0ACK_ISR +{ +} +void stub_isr(void)__interrupt STUB_ISR +{ +} +void ep0in_isr(void)__interrupt EP0IN_ISR +{ +} +void ep0out_isr(void)__interrupt EP0OUT_ISR +{ +} +void ep1in_isr(void)__interrupt EP1IN_ISR +{ + ep1_in = true; + + EXIF &= ~0x10; /* Clear USBINT: Main global interrupt */ + EPIRQ = 0x04; /* Clear individual EP1IN IRQ */ +} +void ep1out_isr(void)__interrupt EP1OUT_ISR +{ + ep1_out = true; + + EXIF &= ~0x10; /* Clear USBINT: Main global interrupt */ + EPIRQ = 0x08; /* Clear individual EP1OUT IRQ */ +} +void ep2_isr(void)__interrupt EP2_ISR +{ + ep1_out = false; /* Does nothing but required by the compiler */ +} +void ep4_isr(void)__interrupt EP4_ISR +{ +} +void ep6_isr(void)__interrupt EP6_ISR +{ +} +void ep8_isr(void)__interrupt EP8_ISR +{ +} +void ibn_isr(void)__interrupt IBN_ISR +{ +} +void ep0pingnak_isr(void)__interrupt EP0PINGNAK_ISR +{ +} +void ep1pingnak_isr(void)__interrupt EP1PINGNAK_ISR +{ +} +void ep2pingnak_isr(void)__interrupt EP2PINGNAK_ISR +{ +} +void ep4pingnak_isr(void)__interrupt EP4PINGNAK_ISR +{ +} +void ep6pingnak_isr(void)__interrupt EP6PINGNAK_ISR +{ +} +void ep8pingnak_isr(void)__interrupt EP8PINGNAK_ISR +{ +} +void errorlimit_isr(void)__interrupt ERRORLIMIT_ISR +{ +} +void ep2piderror_isr(void)__interrupt EP2PIDERROR_ISR +{ +} +void ep4piderror_isr(void)__interrupt EP4PIDERROR_ISR +{ +} +void ep6piderror_isr(void)__interrupt EP6PIDERROR_ISR +{ +} +void ep8piderror_isr(void)__interrupt EP8PIDERROR_ISR +{ +} +void ep2pflag_isr(void)__interrupt EP2PFLAG_ISR +{ +} +void ep4pflag_isr(void)__interrupt EP4PFLAG_ISR +{ +} +void ep6pflag_isr(void)__interrupt EP6PFLAG_ISR +{ +} +void ep8pflag_isr(void)__interrupt EP8PFLAG_ISR +{ +} +void ep2eflag_isr(void)__interrupt EP2EFLAG_ISR +{ +} +void ep4eflag_isr(void)__interrupt EP4EFLAG_ISR +{ +} +void ep6eflag_isr(void)__interrupt EP6EFLAG_ISR +{ +} +void ep8eflag_isr(void)__interrupt EP8EFLAG_ISR +{ +} +void ep2fflag_isr(void)__interrupt EP2FFLAG_ISR +{ +} +void ep4fflag_isr(void)__interrupt EP4FFLAG_ISR +{ +} +void ep6fflag_isr(void)__interrupt EP6FFLAG_ISR +{ +} +void ep8fflag_isr(void)__interrupt EP8FFLAG_ISR +{ +} +void gpifcomplete_isr(void)__interrupt GPIFCOMPLETE_ISR +{ +} +void gpifwaveform_isr(void)__interrupt GPIFWAVEFORM_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 uint8_t *usb_get_endpoint_cs_reg(uint8_t ep) +{ + /* Mask direction bit */ + uint8_t ep_num = ep & ~0x80; + + switch (ep_num) { + case 0: + return &EP0CS; + case 1: + return ep & 0x80 ? &EP1INCS : &EP1OUTCS; + case 2: + return &EP2CS; + case 4: + return &EP4CS; + case 6: + return &EP6CS; + case 8: + return &EP8CS; + default: + return NULL; + } +} + +void usb_reset_data_toggle(uint8_t ep) +{ + /* TOGCTL register: + +----+-----+-----+------+-----+-------+-------+-------+ + | Q | S | R | IO | EP3 | 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. + */ + TOGCTL = (((ep & 0x80) >> 3) + (ep & 0x0F)); + TOGCTL |= BMRESETTOGGLE; +} + +/** + * Handle GET_STATUS request. + * + * @return on success: true + * @return on failure: false + */ +bool usb_handle_get_status(void) +{ + uint8_t *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 */ + EP0BUF[0] = 0; + EP0BUF[1] = 0; + + /* Send response */ + EP0BCH = 0; + syncdelay(3); + EP0BCL = 2; + syncdelay(3); + break; + case GS_INTERFACE: + /* Always return two zero bytes according to USB 1.1 spec, p. 191 */ + EP0BUF[0] = 0; + EP0BUF[1] = 0; + + /* Send response */ + EP0BCH = 0; + syncdelay(3); + EP0BCL = 2; + syncdelay(3); + 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) + EP0BUF[0] = 0x01; + else + EP0BUF[0] = 0x00; + + /* Second byte sent has to be always zero */ + EP0BUF[1] = 0; + + /* Send response */ + EP0BCH = 0; + syncdelay(3); + EP0BCL = 2; + syncdelay(3); + break; + default: + return false; + } + return true; +} + +/** + * Handle CLEAR_FEATURE request. + * + * @return on success: true + * @return on failure: false + */ +bool usb_handle_clear_feature(void) +{ + __xdata uint8_t *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... */ + break; + } + return true; +} + +/** + * Handle SET_FEATURE request. + * + * @return on success: true + * @return on failure: false + */ +bool usb_handle_set_feature(void) +{ + __xdata uint8_t *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 uint8_t descriptor_type; + __xdata uint8_t 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; + } + return true; +} + +/** + * Handle SET_INTERFACE request. + */ +void usb_handle_set_interface(void) +{ + /* Reset Data Toggle */ + usb_reset_data_toggle(USB_DIR_IN | 4); + usb_reset_data_toggle(USB_DIR_OUT | 2); + + /* Unstall & clear busy flag of all valid IN endpoints */ + EP1INCS = 0 | EPBSY; + + /* Unstall all valid OUT endpoints, reset bytecounts */ + EP1OUTCS = 0; + EP1OUTBC = 0; + syncdelay(3); +} + +/* Initialize GPIF interface transfer count */ +void set_gpif_cnt(uint32_t count) +{ + GPIFTCB3 = (uint8_t)(((uint32_t)(count) >> 24) & 0x000000ff); + syncdelay(3); + GPIFTCB2 = (uint8_t)(((uint32_t)(count) >> 16) & 0x000000ff); + syncdelay(3); + GPIFTCB1 = (uint8_t)(((uint32_t)(count) >> 8) & 0x000000ff); + syncdelay(3); + GPIFTCB0 = (uint8_t)((uint32_t)(count) & 0x000000ff); +} + +/* + * Vendor commands handling: +*/ +#define VR_CFGOPEN 0xB0 +#define VR_CFGCLOSE 0xB1 + +uint8_t ix; +uint8_t bcnt; +uint8_t __xdata *eptr; +uint16_t wcnt; +uint32_t __xdata gcnt; +bool usb_handle_send_bitstream(void) +{ + eptr = EP0BUF; /* points to EP0BUF 64-byte register */ + wcnt = setup_data.wlength; /* total transfer count */ + + /* Clear EP0BUF for OUT requests */ + if (setup_data.bmrequesttype & 0x80) { + bcnt = ((wcnt > 64) ? 64 : wcnt); + for (ix = 0; ix < bcnt; ix++) + eptr[ix] = 0; + } + + switch (setup_data.brequest) { + case VR_CFGOPEN: + /* Clear bytecount / to allow new data in / to stops NAKing */ + EP0BCH = 0; + EP0BCL = 0; + while (EP0CS & EPBSY) + ; /* wait to finish transferring in EP0BUF, until not busy */ + gcnt = ((uint32_t)(eptr[0]) << 24) | ((uint32_t)(eptr[1]) << 16) + | ((uint32_t)(eptr[2]) << 8) | (uint32_t)(eptr[3]); + /* Angie board FPGA bitstream download */ + switch ((setup_data.wvalue) & 0x00C0) { + case 0x00: + PIN_PROGRAM_B = 0; /* Apply RPGM- pulse */ + GPIFWFSELECT = 0xF2; /* Restore Config mode waveforms select */ + syncdelay(3); + EP2FIFOCFG = BMAUTOOUT; /* and Automatic 8-bit GPIF OUT mode */ + syncdelay(3); + PIN_PROGRAM_B = 1; /* Negate RPGM- pulse */ + delay_ms(10); /* FPGA init time < 10mS */ + set_gpif_cnt(gcnt); /* Initialize GPIF interface transfer count */ + PIN_RDWR_B = 0; + PIN_CSI_B = 0; + GPIFTRIG = GPIF_EP2; /* Trigger GPIF OUT transfer on EP2 */ + syncdelay(3); + break; + default: + break; + } + break; + case VR_CFGCLOSE: + ix = 10; + /* wait until GPIF transaction has been completed */ + while ((GPIFTRIG & BMGPIFDONE) == 0) { + if (ix-- == 0) { + printf("GPIF done time out\n"); + break; + } + delay_ms(1); + } + switch ((setup_data.wvalue) & 0x00C0) { + case 0x00: + PIN_CSI_B = 1; + PIN_RDWR_B = 1; + IFCONFIG &= 0xFC; /* Exit gpif mode */ + break; + default: + break; + } + EP0BCH = 0; + EP0BCL = (uint8_t)(setup_data.wlength); /* Signal buffer is filled */ + break; + default: + return true; /* Error: unknown VR command */ + } + return false; /* no error; command handled OK */ +} + +/** + * 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: + /* ANGIE has only one configuration, return its index */ + EP0BUF[0] = config_descriptor.bconfigurationvalue; + EP0BCH = 0; + EP0BCL = 1; + syncdelay(3); + break; + case SET_CONFIGURATION: + /* ANGIE has only one configuration -> nothing to do */ + break; + case GET_INTERFACE: + /* ANGIE only has one interface, return its number */ + EP0BUF[0] = interface_descriptor00.binterfacenumber; + EP0BCH = 0; + EP0BCL = 1; + syncdelay(3); + break; + case SET_INTERFACE: + usb_handle_set_interface(); + break; + case SYNCH_FRAME: + /* Isochronous endpoints not used -> nothing to do */ + break; + default: + /* if not Vendor command, Stall EndPoint 0 */ + if (usb_handle_send_bitstream()) + STALL_EP0(); + break; + } +} + +/** + * Handle the initialization of endpoints. + */ +void ep_init(void) +{ + EP1INCFG = 0xA0; + syncdelay(3); + EP1OUTCFG = 0xA0; + syncdelay(3); + EP2CFG = 0xA0; + syncdelay(3); + EP4CFG = 0x00; + syncdelay(3); + EP6CFG = 0x00; + syncdelay(3); + EP8CFG = 0x00; + syncdelay(3); + + /* arm EP1-OUT */ + EP1OUTBC = 0; + syncdelay(3); + EP1OUTBC = 0; + syncdelay(3); + + /* arm EP1-IN */ + EP1INBC = 0; + syncdelay(3); + EP1INBC = 0; + syncdelay(3); + + /* Standard procedure to reset FIFOs */ + FIFORESET = BMNAKALL; /* NAK all transfers during the reset */ + syncdelay(3); + FIFORESET = 0x02; /* reset EP2 FIFO */ + syncdelay(3); + FIFORESET = 0x00; /* deactivate the NAK all */ + syncdelay(3); + EP2FIFOCFG = 0x00; + syncdelay(3); + EP2FIFOCFG = BMAUTOOUT; /* Automatic 8-bit GPIF OUT mode */ + syncdelay(3); +} + +/** + * Interrupt initialization. Configures USB interrupts. + */ +void interrupt_init(void) +{ + /* Enable Interrupts */ + EA = 1; + + /* Enable USB interrupt (EIE register) */ + EUSB = 1; + EICON |= 0x20; + + /* Enable INT 2 & 4 Autovectoring */ + INTSETUP |= (AV2EN | AV4EN); + + /* Enable individual EP1OUT&IN interrupts */ + EPIE |= 0x0C; + + /* Clear individual USB interrupt IRQ */ + EPIRQ = 0x0C; + + /* Enable SUDAV interrupt */ + USBIEN |= SUDAVI; + + /* Clear SUDAV interrupt */ + USBIRQ = SUDAVI; +} + +/** + * Handle the initialization of io ports. + */ +void io_init(void) +{ + /* PORT A */ + PORTACFG = 0x01; /* 0: normal ou 1: alternate function (each bit) */ + OEA = 0xEF; /* all OUT exept INIT_B IN */ + IOA = 0xFF; + PIN_RDWR_B = 1; + PIN_CSI_B = 1; + PIN_PROGRAM_B = 1; + + /* PORT B */ + OEB = 0xEF; /* all OUT exept TDO */ + IOB = 0xFF; + PIN_TRST = 1; + PIN_TMS = 0; + PIN_TCK = 0; + PIN_TDI = 0; + PIN_SRST = 1; + + /* PORT C */ + PORTCCFG = 0x00; /* 0: normal ou 1: alternate function (each bit) */ + OEC = 0xEF; + IOC = 0xFF; +} diff --git a/contrib/firmware/angie/hdl/Makefile b/contrib/firmware/angie/hdl/Makefile new file mode 100644 index 0000000000..c2c74a0b80 --- /dev/null +++ b/contrib/firmware/angie/hdl/Makefile @@ -0,0 +1,109 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (C) 2023 by NanoXplore, France - all rights reserved + +# Needed by timing test +export PROJECT := angie_openocd +TARGET_PART := xc6slx9-2tqg144 +export TOPLEVEL := S609 + +# Detects the ROOT dir from the .git marker +sp := +sp += +_walk = $(if $1,$(wildcard /$(subst $(sp),/,$1)/$2) $(call _walk,$(wordlist 2,$(words $1),x $1),$2)) +_find = $(firstword $(call _walk,$(strip $(subst /, ,$1)),$2)) +_ROOT := $(patsubst %/.git,%,$(call _find,$(CURDIR),.git)) + +SHELL := /bin/bash +TOP_DIR := $(realpath $(_ROOT)) +HDL_DIR := $(CURDIR) +SRC_DIR := $(HDL_DIR)/src +TOOLS_DIR := $(TOP_DIR)/tools/build +COMMON_DIR := $(TOP_DIR)/common/hdl +COMMON_HDL_DIR := $(COMMON_DIR)/src +COMMON_LIBS := $(COMMON_DIR)/libs +HDL_BUILD_DIR := $(HDL_DIR)/build +OUTPUT_DIR ?= $(HDL_BUILD_DIR)/output +FINAL_OUTPUT_DIR := $(OUTPUT_DIR)/$(PROJECT) + +# Tools +MKDIR := mkdir -p +CP := cp -f + +HDL_SRC_PATH := $(addprefix $(COMMON_DIR)/ips/, $(HDL_IPS)) $(HDL_DIR) +VHDSOURCE += $(foreach ip,$(HDL_SRC_PATH),$(wildcard $(ip)/src/*.vhd)) +VSOURCE += $(foreach ip,$(HDL_SRC_PATH),$(wildcard $(ip)/src/*.v)) +VSOURCE += $(foreach ip,$(HDL_SRC_PATH),$(wildcard $(ip)/src/*.vh)) + +CONSTRAINTS ?= $(SRC_DIR)/$(PROJECT).ucf + +COMMON_OPTS := -intstyle xflow +XST_OPTS := +NGDBUILD_OPTS := +MAP_OPTS := -mt 2 +PAR_OPTS := -mt 4 +BITGEN_OPTS := -g Binary:Yes + +XILINX_PLATFORM := lin64 +PATH := $(PATH):$(XILINX_HOME)/bin/$(XILINX_PLATFORM) + +RUN = @echo -ne "\n\n\e[1;33m======== $(1) ========\e[m\n\n"; \ + cd $(HDL_BUILD_DIR) && $(XILINX_HOME)/bin/$(XILINX_PLATFORM)/$(1) + +compile: $(HDL_BUILD_DIR)/$(PROJECT).bin + +install: $(HDL_BUILD_DIR)/$(PROJECT).bin + $(MKDIR) $(FINAL_OUTPUT_DIR) + $(CP) $(HDL_BUILD_DIR)/$(PROJECT).bin $(FINAL_OUTPUT_DIR) + +clean: + rm -rf $(HDL_BUILD_DIR) + +$(HDL_BUILD_DIR)/$(PROJECT).bin: $(HDL_BUILD_DIR)/$(PROJECT).ncd + $(call RUN,bitgen) $(COMMON_OPTS) $(BITGEN_OPTS) \ + -w $(PROJECT).ncd $(PROJECT).bit + +$(HDL_BUILD_DIR)/$(PROJECT).ncd: $(HDL_BUILD_DIR)/$(PROJECT).map.ncd + $(call RUN,par) $(COMMON_OPTS) $(PAR_OPTS) \ + -w $(PROJECT).map.ncd $(PROJECT).ncd $(PROJECT).pcf + +$(HDL_BUILD_DIR)/$(PROJECT).map.ncd: $(HDL_BUILD_DIR)/$(PROJECT).ngd + $(call RUN,map) $(COMMON_OPTS) $(MAP_OPTS) \ + -p $(TARGET_PART) \ + -w $(PROJECT).ngd -o $(PROJECT).map.ncd $(PROJECT).pcf + +$(HDL_BUILD_DIR)/$(PROJECT).ngd: $(HDL_BUILD_DIR)/$(PROJECT).ngc + $(call RUN,ngdbuild) $(COMMON_OPTS) $(NGDBUILD_OPTS) \ + -p $(TARGET_PART) -uc $(CONSTRAINTS) \ + $(PROJECT).ngc $(PROJECT).ngd + +$(HDL_BUILD_DIR)/$(PROJECT).ngc: $(HDL_BUILD_DIR)/$(PROJECT).prj $(HDL_BUILD_DIR)/$(PROJECT).scr + $(call RUN,xst) $(COMMON_OPTS) -ifn $(PROJECT).scr + +$(HDL_BUILD_DIR)/$(PROJECT).scr: | $(HDL_BUILD_DIR) + @echo "Updating $@" + @mkdir -p $(HDL_BUILD_DIR) + @rm -f $@ + @echo "run" \ + "-ifn $(PROJECT).prj" \ + "-ofn $(PROJECT).ngc" \ + "-ifmt mixed" \ + "$(XST_OPTS)" \ + "-top $(TOPLEVEL)" \ + "-ofmt NGC" \ + "-p $(TARGET_PART)" \ + > $(HDL_BUILD_DIR)/$(PROJECT).scr + +$(HDL_BUILD_DIR)/$(PROJECT).prj: | $(HDL_BUILD_DIR) + @echo "Updating $@" + @rm -f $@ + @$(foreach file,$(VSOURCE),echo "verilog work \"$(file)\"" >> $@;) + @$(foreach file,$(VHDSOURCE),echo "vhdl work \"$(file)\"" >> $@;) + @$(foreach lib,$(HDL_LIBS),$(foreach file,$(wildcard $(COMMON_LIBS)/$(lib)/src/*.vhd),echo "vhdl $(lib) \"$(file)\"" >> $@;)) + @$(foreach lib,$(HDL_LIBS),$(foreach file,$(wildcard $(COMMON_LIBS)/$(lib)/src/*.v),echo "verilog $(lib) \"$(file)\"" >> $@;)) + @$(foreach lib,$(HDL_LIBS),$(foreach file,$(wildcard $(COMMON_LIBS)/$(lib)/src/*.vh),echo "verilog $(lib) \"$(file)\"" >> $@;)) + +$(HDL_BUILD_DIR): + $(MKDIR) $(HDL_BUILD_DIR) + +.PHONY: clean compile install + diff --git a/contrib/firmware/angie/hdl/README b/contrib/firmware/angie/hdl/README new file mode 100644 index 0000000000..00578ff729 --- /dev/null +++ b/contrib/firmware/angie/hdl/README @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (C) 2023 by NanoXplore, France - all rights reserved + +This is the source code of Nanoxplore USB-JTAG Adapter Angie's bitstream. +This bitstream is for the "xc6slx9-2tqg144" Spartan-6 Xilinx FPGA. + +To generate this bitstream, you need to install Xilinx ISE Webpack 14.7 +You will need to give the ISE software path : export XILINX_HOME=path/to/ise/sw +Please set the enviromnent first by executing the ". ./set_env.sh" + +All you have to do now is to write your vhd and constrains codes. + +One all is setup, you can use the make commands: + make compile : to compile your (.vhd & .ucf) files in the "src" directory + A directory named "build" will be created, which contains all the generated + files including the bitstream file. + + make clean : to delete the build directory. diff --git a/contrib/firmware/angie/hdl/set_env.sh b/contrib/firmware/angie/hdl/set_env.sh new file mode 100644 index 0000000000..60e97375b9 --- /dev/null +++ b/contrib/firmware/angie/hdl/set_env.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (C) 2023 by NanoXplore, France - all rights reserved + +[ -z "${XILINX_HOME}" ] && export XILINX_HOME=/home/software/Xilinx/ISE/14.7/ISE_DS/ISE +export PATH="$XILINX_HOME:$PATH" +echo "SET XILINX_HOME to ${XILINX_HOME}" +# This is needed for isim +XILINX_HOME_BASE=${XILINX_HOME}/.. +for part in common EDK PlanAhead ISE +do + el=${XILINX_HOME_BASE}/${part} + . ${el}/.settings64.sh ${el} +done diff --git a/contrib/firmware/angie/hdl/src/angie_openocd.ucf b/contrib/firmware/angie/hdl/src/angie_openocd.ucf new file mode 100644 index 0000000000..fda3cdaaf1 --- /dev/null +++ b/contrib/firmware/angie/hdl/src/angie_openocd.ucf @@ -0,0 +1,35 @@ +## SPDX-License-Identifier: BSD-3-Clause +##-------------------------------------------------------------------------- +## Project Context: nanoXplore USB-JTAG Adapter Board, Spartan6 +## Design Name: NJTAG USB-JTAG Adapter FPGA source code +## Module Name: _angie_openocd.ucf +## Target Device: XC6SLX9-2 TQ144 +## Tool versions: ISE Webpack 13.2 -> 14.2 +## Author: Ahmed BOUDJELIDA nanoXplore SAS +##-------------------------------------------------------------------------- +# WARNING: PullUps on JTAG inputs should be enabled after configuration +# (bitgen option) since the pins are not connected. + +net TRST LOC = 'P48' ; +net TMS LOC = 'P43' ; +net TCK LOC = 'P44' ; +net TDI LOC = 'P45' ; +net TDO LOC = 'P46' ; +net SRST LOC = 'P61' ; +net SI_TDO LOC = 'P16' ; +net SO_TRST LOC = 'P32' ; +net SO_TMS LOC = 'P27' ; +net SO_TCK LOC = 'P30' ; +net SO_TDI LOC = 'P26' ; +net SO_SRST LOC = 'P12' ; +net ST_0 LOC = 'P29' ; +net ST_1 LOC = 'P21' ; +net ST_2 LOC = 'P11' ; +net FTP<0> LOC = 'P121' ; +net FTP<1> LOC = 'P120' ; +net FTP<2> LOC = 'P119' ; +net FTP<3> LOC = 'P116' ; +net FTP<4> LOC = 'P111' ; +net FTP<5> LOC = 'P112' ; +net FTP<6> LOC = 'P115' ; +net FTP<7> LOC = 'P114' ; diff --git a/contrib/firmware/angie/hdl/src/angie_openocd.vhd b/contrib/firmware/angie/hdl/src/angie_openocd.vhd new file mode 100644 index 0000000000..d79c0fecef --- /dev/null +++ b/contrib/firmware/angie/hdl/src/angie_openocd.vhd @@ -0,0 +1,66 @@ +-- SPDX-License-Identifier: BSD-3-Clause +---------------------------------------------------------------------------- +-- Project Context: nanoXplore USB-JTAG Adapter Board, Spartan6 +-- Design Name: NJTAG USB-JTAG Adapter FPGA source code +-- Module Name: _angie_openocd.vhd +-- Target Device: XC6SLX9-2 TQ144 +-- Tool versions: ISE Webpack 13.2 -> 14.2 +-- Author: Ahmed BOUDJELIDA nanoXplore SAS +---------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +library UNISIM; +use UNISIM.VComponents.all; + +entity S609 is port( + TRST : in std_logic; + TMS : in std_logic; + TCK : in std_logic; + TDI : in std_logic; + TDO : out std_logic; + SRST : in std_logic; + FTP : out std_logic_vector(7 downto 0); -- Test points + SI_TDO : in std_logic; + ST_0 : out std_logic; + ST_1 : out std_logic; + ST_2 : out std_logic; + SO_TRST : out std_logic; + SO_TMS : out std_logic; + SO_TCK : out std_logic; + SO_TDI : out std_logic; + SO_SRST :out std_logic +); +end S609; + +architecture A_S609 of S609 is +begin + +--Directions: +ST_0 <= '0'; +ST_1 <= '1'; + +--TDO: +TDO <= not SI_TDO; + +--TRST - TCK - TMS - TDI: +SO_TRST <= TRST; +SO_TMS <= TMS; +SO_TCK <= TCK; +SO_TDI <= TDI; +ST_2 <= SRST; +SO_SRST <= '0'; + +--Points de test: +FTP(0) <= TRST; +FTP(1) <= TMS; +FTP(2) <= TCK; +FTP(3) <= TDI; +FTP(5) <= SRST; +FTP(4) <= SI_TDO; +FTP(6) <= '1'; +FTP(7) <= '1'; + +end A_S609; diff --git a/doc/usb_adapters/angie/584e_424e_angie.txt b/doc/usb_adapters/angie/584e_424e_angie.txt new file mode 100644 index 0000000000..8162cbad5a --- /dev/null +++ b/doc/usb_adapters/angie/584e_424e_angie.txt @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later + +Bus 001 Device 056: ID 584e:424e NanoXplore, SAS. ANGIE Adapter +Device Descriptor: + bLength 18 + bDescriptorType 1 + bcdUSB 2.00 + bDeviceClass 255 Vendor Specific Class + bDeviceSubClass 255 Vendor Specific Subclass + bDeviceProtocol 255 Vendor Specific Protocol + bMaxPacketSize0 64 + idVendor 0x584e + idProduct 0x424e + bcdDevice 0.00 + iManufacturer 1 NanoXplore, SAS. + iProduct 2 ANGIE Adapter + iSerial 3 000001 + bNumConfigurations 1 + Configuration Descriptor: + bLength 9 + bDescriptorType 2 + wTotalLength 0x0027 + bNumInterfaces 1 + bConfigurationValue 1 + iConfiguration 4 (error) + bmAttributes 0x80 + (Bus Powered) + MaxPower 100mA + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 0 + bAlternateSetting 0 + bNumEndpoints 3 + bInterfaceClass 255 Vendor Specific Class + bInterfaceSubClass 255 Vendor Specific Subclass + bInterfaceProtocol 255 Vendor Specific Protocol + iInterface 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x01 EP 1 OUT + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0040 1x 64 bytes + bInterval 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x81 EP 1 IN + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0040 1x 64 bytes + bInterval 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x02 EP 2 OUT + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0200 1x 512 bytes + bInterval 0 -- 2.30.2