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 <aboudjelida@nanoxplore.com> Reviewed-on: https://review.openocd.org/c/openocd/+/7701 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
parent
3b78b5c1db
commit
9c91ce8d24
|
@ -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. *
|
||||
# <aboudjelida@nanoxplore.com> *
|
||||
# <ahmederrachedbjld@gmail.com> *
|
||||
# ***************************************************************************/
|
||||
|
||||
# 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
|
|
@ -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.
|
|
@ -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. *
|
||||
<aboudjelida@nanoxplore.com> *
|
||||
<ahmederrachedbjld@gmail.com> *
|
||||
*****************************************************************/
|
||||
|
||||
#ifndef __DELAY_H
|
||||
#define __DELAY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
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
|
|
@ -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
|
|
@ -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. *
|
||||
<aboudjelida@nanoxplore.com> *
|
||||
<ahmederrachedbjld@gmail.com> *
|
||||
*****************************************************************************/
|
||||
|
||||
#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
|
|
@ -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. *
|
||||
<aboudjelida@nanoxplore.com> *
|
||||
<ahmederrachedbjld@gmail.com> *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __JTAG_H
|
||||
#define __JTAG_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
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
|
|
@ -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. *
|
||||
<aboudjelida@nanoxplore.com> *
|
||||
<ahmederrachedbjld@gmail.com> *
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @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
|
|
@ -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. *
|
||||
<aboudjelida@nanoxplore.com> *
|
||||
<ahmederrachedbjld@gmail.com> *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __PROTOCOL_H
|
||||
#define __PROTOCOL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
bool execute_command(void);
|
||||
void command_loop(void);
|
||||
|
||||
#endif
|
|
@ -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. *
|
||||
<aboudjelida@nanoxplore.com> *
|
||||
<ahmederrachedbjld@gmail.com> *
|
||||
*****************************************************************************/
|
||||
|
||||
#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 <mcs51/compiler.h>
|
||||
|
||||
/* Bit vectors */
|
||||
#define bmbit0 0x01
|
||||
#define bmbit1 0x02
|
||||
#define bmbit2 0x04
|
||||
#define bmbit3 0x08
|
||||
#define bmbit4 0x10
|
||||
#define bmbit5 0x20
|
||||
#define bmbit6 0x40
|
||||
#define bmbit7 0x80
|
||||
|
||||
/**************************************************************************
|
||||
************************ Special Function Registers **********************
|
||||
***************************************************************************/
|
||||
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
|
|
@ -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 <stdint.h>
|
||||
/**
|
||||
* 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);
|
|
@ -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. *
|
||||
<aboudjelida@nanoxplore.com> *
|
||||
<ahmederrachedbjld@gmail.com> *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __USB_H
|
||||
#define __USB_H
|
||||
|
||||
#include "reg_ezusb.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/* 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
|
|
@ -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. *
|
||||
; <aboudjelida@nanoxplore.com> *
|
||||
; <ahmederrachedbjld@gmail.com> *
|
||||
;****************************************************************************
|
||||
.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
|
|
@ -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. *
|
||||
<aboudjelida@nanoxplore.com> *
|
||||
<ahmederrachedbjld@gmail.com> *
|
||||
*****************************************************************************/
|
||||
|
||||
#include "delay.h"
|
||||
#include <mcs51/compiler.h>
|
||||
|
||||
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();
|
||||
}
|
|
@ -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];
|
||||
}
|
|
@ -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. *
|
||||
<aboudjelida@nanoxplore.com> *
|
||||
<ahmederrachedbjld@gmail.com> *
|
||||
*****************************************************************************/
|
||||
|
||||
#include "jtag.h"
|
||||
#include "io.h"
|
||||
#include "msgtypes.h"
|
||||
#include "reg_ezusb.h"
|
||||
#include <stdbool.h>
|
||||
#include <serial.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/** 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;
|
||||
}
|
|
@ -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. *
|
||||
<aboudjelida@nanoxplore.com> *
|
||||
<ahmederrachedbjld@gmail.com> *
|
||||
*****************************************************************************/
|
||||
|
||||
#include "usb.h"
|
||||
#include "delay.h"
|
||||
#include "protocol.h"
|
||||
#include "reg_ezusb.h"
|
||||
#include <serial.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern void sudav_isr(void)__interrupt SUDAV_ISR;
|
||||
extern void sof_isr(void)__interrupt;
|
||||
extern void sutok_isr(void)__interrupt;
|
||||
extern void suspend_isr(void)__interrupt;
|
||||
extern void usbreset_isr(void)__interrupt;
|
||||
extern void 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;
|
||||
}
|
|
@ -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. *
|
||||
<aboudjelida@nanoxplore.com> *
|
||||
<ahmederrachedbjld@gmail.com> *
|
||||
*****************************************************************************/
|
||||
|
||||
#include "usb.h"
|
||||
#include "protocol.h"
|
||||
#include "jtag.h"
|
||||
#include "delay.h"
|
||||
#include "io.h"
|
||||
#include "msgtypes.h"
|
||||
#include "reg_ezusb.h"
|
||||
#include <serial.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/** 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);
|
||||
}
|
||||
}
|
|
@ -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 <reg_ezusb.h>
|
||||
#include <fx2macros.h>
|
||||
#include <serial.h>
|
||||
#include <stdint.h>
|
||||
/**
|
||||
* 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;
|
||||
}
|
|
@ -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. *
|
||||
<aboudjelida@nanoxplore.com> *
|
||||
<ahmederrachedbjld@gmail.com> *
|
||||
*****************************************************************************/
|
||||
|
||||
#include "usb.h"
|
||||
#include "stdint.h"
|
||||
#include "delay.h"
|
||||
#include "io.h"
|
||||
#include "reg_ezusb.h"
|
||||
#include <fx2macros.h>
|
||||
#include <serial.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* 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;
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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.
|
|
@ -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
|
|
@ -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' ;
|
|
@ -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;
|
|
@ -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
|
Loading…
Reference in New Issue