contrib/firmware: add new i2c bit-banging feature to angie's firmware

add new i2c bit-banging feature, we can now connect in JTAG with the SoC
target and in i2c with the main board components at the same time.

Change-Id: I8e4516fe1ad5238e0373444f1c3c9bc0814d0f52
Signed-off-by: Ahmed BOUDJELIDA <aboudjelida@nanoxplore.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/7796
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
Ahmed BOUDJELIDA 2023-08-16 17:05:05 +02:00 committed by Antonio Borneo
parent aa0056d273
commit aee495e785
14 changed files with 534 additions and 139 deletions

View File

@ -38,7 +38,7 @@ LDFLAGS = --code-loc 0x0000 --code-size $(CODE_SIZE) --xram-loc $(XRAM_LOC) \
--xram-size $(XRAM_SIZE) --iram-size 256 --model-small --xram-size $(XRAM_SIZE) --iram-size 256 --model-small
# list of base object files # list of base object files
OBJECTS = main.rel usb.rel protocol.rel jtag.rel delay.rel USBJmpTb.rel serial.rel gpif.rel OBJECTS = main.rel usb.rel protocol.rel jtag.rel delay.rel USBJmpTb.rel serial.rel gpif.rel i2c.rel
HEADERS = $(INCLUDE_DIR)/usb.h \ HEADERS = $(INCLUDE_DIR)/usb.h \
$(INCLUDE_DIR)/protocol.h \ $(INCLUDE_DIR)/protocol.h \
$(INCLUDE_DIR)/jtag.h \ $(INCLUDE_DIR)/jtag.h \
@ -47,7 +47,8 @@ HEADERS = $(INCLUDE_DIR)/usb.h \
$(INCLUDE_DIR)/io.h \ $(INCLUDE_DIR)/io.h \
$(INCLUDE_DIR)/serial.h \ $(INCLUDE_DIR)/serial.h \
$(INCLUDE_DIR)/fx2macros.h \ $(INCLUDE_DIR)/fx2macros.h \
$(INCLUDE_DIR)/msgtypes.h $(INCLUDE_DIR)/msgtypes.h \
$(INCLUDE_DIR)/i2c.h
# Disable all built-in rules. # Disable all built-in rules.
.SUFFIXES: .SUFFIXES:
@ -61,7 +62,7 @@ all: angie_firmware.ihx
angie_firmware.ihx: $(OBJECTS) angie_firmware.ihx: $(OBJECTS)
$(CC) -mmcs51 $(LDFLAGS) -o $@ $^ $(CC) -mmcs51 $(LDFLAGS) -o $@ $^
# Rebuild every C module (there are only 5 of them) if any header changes. # Rebuild every C module (there are only 8 of them) if any header changes.
%.rel: $(SRC_DIR)/%.c $(HEADERS) %.rel: $(SRC_DIR)/%.c $(HEADERS)
$(CC) -c $(CFLAGS) -mmcs51 -I$(INCLUDE_DIR) -o $@ $< $(CC) -c $(CFLAGS) -mmcs51 -I$(INCLUDE_DIR) -o $@ $<

View File

@ -12,8 +12,8 @@ To compile the firmware, the SDCC compiler package is required. Most Linux
distributions include SDCC in their official package repositories. The SDCC distributions include SDCC in their official package repositories. The SDCC
source code can be found at http://sdcc.sourceforge.net/ source code can be found at http://sdcc.sourceforge.net/
Simply type "make hex" in the ANGIE directory to compile the firmware. Simply type "make bin" in the ANGIE directory to compile the firmware.
"make clean" will remove all generated files except the Intel HEX file "make clean" will remove all generated files except the BIN file
required for downloading the firmware to ANGIE. required for downloading the firmware to ANGIE.
Note that the EZ-USB FX2 microcontroller does not have on-chip flash, Note that the EZ-USB FX2 microcontroller does not have on-chip flash,

View File

@ -0,0 +1,28 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/****************************************************************************
File : i2c.h *
Contents : i2c bit-bang library *
Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. *
<aboudjelida@nanoxplore.com> *
<ahmederrachedbjld@gmail.com> *
*****************************************************************************/
#ifndef __I2C_H
#define __I2C_H
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
void start_cd(void);
void repeated_start(void);
void stop_cd(void);
void clock_cd(void);
void send_ack(void);
bool get_ack(void);
uint8_t get_address(uint8_t adr, uint8_t rdwr);
void send_byte(uint8_t input);
uint8_t receive_byte(void);
#endif

View File

@ -45,14 +45,14 @@
#define PIN_TDI IOB3 #define PIN_TDI IOB3
#define PIN_TDO IOB4 #define PIN_TDO IOB4
#define PIN_SRST IOB5 #define PIN_SRST IOB5
/* PA6 Not Connected */ /* PB6 Not Connected */
/* PA7 Not Connected */ /* PB7 Not Connected */
/* JTAG Signals with direction 'OUT' on port B */ /* JTAG Signals with direction 'OUT' on port B */
/* PIN_TDI - PIN_TCK - PIN_TMS - PIN_TRST - PIN_SRST */ /* PIN_TDI - PIN_TCK - PIN_TMS - PIN_TRST - PIN_SRST */
#define MASK_PORTB_DIRECTION_OUT (bmbit0 | bmbit1 | bmbit2 | bmbit3 | bmbit5) #define MASK_PORTB_DIRECTION_OUT (bmbit0 | bmbit1 | bmbit2 | bmbit3 | bmbit5)
/* PORT C */ // Debug: /* PORT C */
#define PIN_T0 IOC0 #define PIN_T0 IOC0
#define PIN_T1 IOC1 #define PIN_T1 IOC1
#define PIN_T2 IOC2 #define PIN_T2 IOC2
@ -62,4 +62,14 @@
/* PC6 Not Connected */ /* PC6 Not Connected */
/* PC7 Not Connected */ /* PC7 Not Connected */
/* PORT D */
#define PIN_SDA IOD0
#define PIN_SCL IOD1
#define PIN_SDA_DIR IOD2
/* PD3 Not Connected */
/* PD4 Not Connected */
/* PD5 Not Connected */
/* PD6 Not Connected */
/* PD7 Not Connected */
#endif #endif

View File

@ -24,18 +24,19 @@
#define STALL_EP0() (EP0CS |= EPSTALL) #define STALL_EP0() (EP0CS |= EPSTALL)
#define CLEAR_IRQ() (USBINT = 0) #define CLEAR_IRQ() (USBINT = 0)
/*********** USB descriptors. See section 9.5 of the USB 1.1 spec **********/ /*********** USB descriptors. See USB 2.0 Spec **********/
/* USB Descriptor Types. See USB 1.1 spec, page 187, table 9-5 */ /* USB Descriptor Types. See USB 2.0 Spec */
#define DESCRIPTOR_TYPE_DEVICE 0x01 #define DESCRIPTOR_TYPE_DEVICE 0x01
#define DESCRIPTOR_TYPE_CONFIGURATION 0x02 #define DESCRIPTOR_TYPE_CONFIGURATION 0x02
#define DESCRIPTOR_TYPE_STRING 0x03 #define DESCRIPTOR_TYPE_STRING 0x03
#define DESCRIPTOR_TYPE_INTERFACE 0x04 #define DESCRIPTOR_TYPE_INTERFACE 0x04
#define DESCRIPTOR_TYPE_ENDPOINT 0x05 #define DESCRIPTOR_TYPE_ENDPOINT 0x05
#define DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION 0x0B
#define STR_DESCR(len, ...) { (len) * 2 + 2, DESCRIPTOR_TYPE_STRING, { __VA_ARGS__ } } #define STR_DESCR(len, ...) { (len) * 2 + 2, DESCRIPTOR_TYPE_STRING, { __VA_ARGS__ } }
/** USB Device Descriptor. See USB 1.1 spec, pp. 196 - 198 */ /** USB Device Descriptor. See USB 2.0 Spec */
struct usb_device_descriptor { struct usb_device_descriptor {
uint8_t blength; /**< Size of this descriptor in bytes. */ uint8_t blength; /**< Size of this descriptor in bytes. */
uint8_t bdescriptortype; /**< DEVICE Descriptor Type. */ uint8_t bdescriptortype; /**< DEVICE Descriptor Type. */
@ -53,7 +54,7 @@ struct usb_device_descriptor {
uint8_t bnumconfigurations; /**< Number of possible configurations. */ uint8_t bnumconfigurations; /**< Number of possible configurations. */
}; };
/** USB Configuration Descriptor. See USB 1.1 spec, pp. 199 - 200 */ /** USB Configuration Descriptor. See USB 2.0 Spec */
struct usb_config_descriptor { struct usb_config_descriptor {
uint8_t blength; /**< Size of this descriptor in bytes. */ uint8_t blength; /**< Size of this descriptor in bytes. */
uint8_t bdescriptortype; /**< CONFIGURATION descriptor type. */ uint8_t bdescriptortype; /**< CONFIGURATION descriptor type. */
@ -65,7 +66,19 @@ struct usb_config_descriptor {
uint8_t maxpower; /**< Maximum power consumption in 2 mA units. */ uint8_t maxpower; /**< Maximum power consumption in 2 mA units. */
}; };
/** USB Interface Descriptor. See USB 1.1 spec, pp. 201 - 203 */ /** USB Interface association Descriptor. See USB 2.0 Spec */
struct usb_interface_association_descriptor {
uint8_t blength;
uint8_t bdescriptortype;
uint8_t bfirstinterface;
uint8_t binterfacecount;
uint8_t bfunctionclass;
uint8_t bfunctionsubclass;
uint8_t bfunctionprotocol;
uint8_t ifunction;
};
/** USB Interface Descriptor. See USB 2.0 Spec */
struct usb_interface_descriptor { struct usb_interface_descriptor {
uint8_t blength; /**< Size of this descriptor in bytes. */ uint8_t blength; /**< Size of this descriptor in bytes. */
uint8_t bdescriptortype; /**< INTERFACE descriptor type. */ uint8_t bdescriptortype; /**< INTERFACE descriptor type. */
@ -78,7 +91,7 @@ struct usb_interface_descriptor {
uint8_t iinterface; /**< Index of interface string descriptor. */ uint8_t iinterface; /**< Index of interface string descriptor. */
}; };
/** USB Endpoint Descriptor. See USB 1.1 spec, pp. 203 - 204 */ /** USB Endpoint Descriptor. See USB 2.0 Spec */
struct usb_endpoint_descriptor { struct usb_endpoint_descriptor {
uint8_t blength; /**< Size of this descriptor in bytes. */ uint8_t blength; /**< Size of this descriptor in bytes. */
uint8_t bdescriptortype; /**< ENDPOINT descriptor type. */ uint8_t bdescriptortype; /**< ENDPOINT descriptor type. */
@ -88,14 +101,14 @@ struct usb_endpoint_descriptor {
uint8_t binterval; /**< Polling interval (in ms) for this endpoint. */ uint8_t binterval; /**< Polling interval (in ms) for this endpoint. */
}; };
/** USB Language Descriptor. See USB 1.1 spec, pp. 204 - 205 */ /** USB Language Descriptor. See USB 2.0 Spec */
struct usb_language_descriptor { struct usb_language_descriptor {
uint8_t blength; /**< Size of this descriptor in bytes. */ uint8_t blength; /**< Size of this descriptor in bytes. */
uint8_t bdescriptortype; /**< STRING descriptor type. */ uint8_t bdescriptortype; /**< STRING descriptor type. */
uint16_t wlangid[]; /**< LANGID codes. */ uint16_t wlangid[]; /**< LANGID codes. */
}; };
/** USB String Descriptor. See USB 1.1 spec, pp. 204 - 205 */ /** USB String Descriptor. See USB 2.0 Spec */
struct usb_string_descriptor { struct usb_string_descriptor {
uint8_t blength; /**< Size of this descriptor in bytes. */ uint8_t blength; /**< Size of this descriptor in bytes. */
uint8_t bdescriptortype; /**< STRING descriptor type. */ uint8_t bdescriptortype; /**< STRING descriptor type. */
@ -104,7 +117,7 @@ struct usb_string_descriptor {
/********************** USB Control Endpoint 0 related *********************/ /********************** USB Control Endpoint 0 related *********************/
/** USB Control Setup Data. See USB 1.1 spec, pp. 183 - 185 */ /** USB Control Setup Data. See USB 2.0 Spec */
struct setup_data { struct setup_data {
uint8_t bmrequesttype; /**< Characteristics of a request. */ uint8_t bmrequesttype; /**< Characteristics of a request. */
uint8_t brequest; /**< Specific request. */ uint8_t brequest; /**< Specific request. */
@ -121,66 +134,66 @@ extern volatile bool ep1_in;
extern volatile __xdata __at 0xE6B8 struct setup_data setup_data; extern volatile __xdata __at 0xE6B8 struct setup_data setup_data;
/* /*
* USB Request Types (bmRequestType): See USB 1.1 spec, page 183, table 9-2 * USB Request Types (bmRequestType): See USB 2.0 Spec
* *
* Bit 7: Data transfer direction * Bit 7: Data transfer direction
* 0 = Host-to-device * 0 = Host-to-device
* 1 = Device-to-host * 1 = Device-to-host
* Bit 6...5: Type * Bit 6...5: Type
* 0 = Standard * 0 = Standard
* 1 = Class * 1 = Class
* 2 = Vendor * 2 = Vendor
* 3 = Reserved * 3 = Reserved
* Bit 4...0: Recipient * Bit 4...0: Recipient
* 0 = Device * 0 = Device
* 1 = Interface * 1 = Interface
* 2 = Endpoint * 2 = Endpoint
* 3 = Other * 3 = Other
* 4...31 = Reserved * 4...31 = Reserved
*/ */
#define USB_DIR_OUT 0x00 #define USB_DIR_OUT 0x00
#define USB_DIR_IN 0x80 #define USB_DIR_IN 0x80
#define USB_REQ_TYPE_STANDARD (0x00 << 5) #define USB_REQ_TYPE_STANDARD (0x00 << 5)
#define USB_REQ_TYPE_CLASS (0x01 << 5) #define USB_REQ_TYPE_CLASS (0x01 << 5)
#define USB_REQ_TYPE_VENDOR (0x02 << 5) #define USB_REQ_TYPE_VENDOR (0x02 << 5)
#define USB_REQ_TYPE_RESERVED (0x03 << 5) #define USB_REQ_TYPE_RESERVED (0x03 << 5)
#define USB_RECIP_DEVICE 0x00 #define USB_RECIP_DEVICE 0x00
#define USB_RECIP_INTERFACE 0x01 #define USB_RECIP_INTERFACE 0x01
#define USB_RECIP_ENDPOINT 0x02 #define USB_RECIP_ENDPOINT 0x02
#define USB_RECIP_OTHER 0x03 #define USB_RECIP_OTHER 0x03
/* Clear Interface Request */ /* Clear Interface Request */
#define CF_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE) #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_INTERFACE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)
#define CF_ENDPOINT (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT) #define CF_ENDPOINT (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT)
/* Get Configuration Request */ /* Get Configuration Request */
#define GC_DEVICE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE) #define GC_DEVICE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
/* Get Descriptor Request */ /* Get Descriptor Request */
#define GD_DEVICE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE) #define GD_DEVICE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
/* Get Interface Request */ /* Get Interface Request */
#define GI_INTERFACE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE) #define GI_INTERFACE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)
/* Get Status Request: See USB 1.1 spec, page 190 */ /* 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_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_INTERFACE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)
#define GS_ENDPOINT (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT) #define GS_ENDPOINT (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT)
/* Set Address Request is handled by EZ-USB core */ /* Set Address Request is handled by EZ-USB core */
/* Set Configuration Request */ /* Set Configuration Request */
#define SC_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE) #define SC_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
/* Set Descriptor Request */ /* Set Descriptor Request */
#define SD_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE) #define SD_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
/* Set Feature Request */ /* Set Feature Request */
#define SF_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE) #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_INTERFACE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)
#define SF_ENDPOINT (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT) #define SF_ENDPOINT (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT)
@ -190,27 +203,27 @@ extern volatile __xdata __at 0xE6B8 struct setup_data setup_data;
/* Synch Frame Request */ /* Synch Frame Request */
#define SY_ENDPOINT (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT) #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 */ /* USB Requests (bRequest): See USB 2.0 Spec */
#define GET_STATUS 0 #define GET_STATUS 0
#define CLEAR_FEATURE 1 #define CLEAR_FEATURE 1
/* Value '2' is reserved for future use */ /* Value '2' is reserved for future use */
#define SET_FEATURE 3 #define SET_FEATURE 3
/* Value '4' is reserved for future use */ /* Value '4' is reserved for future use */
#define SET_ADDRESS 5 #define SET_ADDRESS 5
#define GET_DESCRIPTOR 6 #define GET_DESCRIPTOR 6
#define SET_DESCRIPTOR 7 #define SET_DESCRIPTOR 7
#define GET_CONFIGURATION 8 #define GET_CONFIGURATION 8
#define SET_CONFIGURATION 9 #define SET_CONFIGURATION 9
#define GET_INTERFACE 10 #define GET_INTERFACE 10
#define SET_INTERFACE 11 #define SET_INTERFACE 11
#define SYNCH_FRAME 12 #define SYNCH_FRAME 12
/* Standard Feature Selectors: See USB 1.1 spec, table 9-6 on page 188 */ /* Standard Feature Selectors: See USB 2.0 Spec */
#define DEVICE_REMOTE_WAKEUP 1 #define DEVICE_REMOTE_WAKEUP 1
#define ENDPOINT_HALT 0 #define ENDPOINT_HALT 0
/************************** EZ-USB specific stuff **************************/ /************************** EZ-USB specific stuff **************************/
/** USB Interrupts. See AN2131-TRM, page 9-4 for details */ /** USB Interrupts. See EZ-USB FX2-TRM, for details */
enum usb_isr { enum usb_isr {
SUDAV_ISR = 13, SUDAV_ISR = 13,
SOF_ISR, SOF_ISR,
@ -265,7 +278,10 @@ bool usb_handle_set_feature(void);
bool usb_handle_get_descriptor(void); bool usb_handle_get_descriptor(void);
void usb_handle_set_interface(void); void usb_handle_set_interface(void);
void usb_handle_setup_data(void); void usb_handle_setup_data(void);
void usb_handle_i2c_in(void);
void usb_handle_i2c_out(void);
void i2c_recieve(void);
void ep_init(void); void ep_init(void);
void interrupt_init(void); void interrupt_init(void);
void io_init(void); void io_init(void);

View File

@ -0,0 +1,127 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/****************************************************************************
File : i2c.cpp *
Contents : i2c bit-bang library *
Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. *
<aboudjelida@nanoxplore.com> *
<ahmederrachedbjld@gmail.com> *
*****************************************************************************/
#include "i2c.h"
#include "io.h"
#include "delay.h"
#include "reg_ezusb.h"
void start_cd(void)
{
PIN_SDA = 0; //SDA = 1;
delay_us(1);
PIN_SCL = 0; //SCL = 1;
delay_us(1);
}
void repeated_start(void)
{
PIN_SDA = 1;
delay_us(1);
PIN_SCL = 1;
delay_us(1);
PIN_SDA = 0;
delay_us(1);
PIN_SCL = 0;
delay_us(1);
}
void stop_cd(void)
{
PIN_SDA = 0;
delay_us(1);
PIN_SCL = 1;
delay_us(1);
PIN_SDA = 1;
delay_us(1);
}
void clock_cd(void)
{
PIN_SCL = 1;
delay_us(1);
PIN_SCL = 0;
delay_us(1);
}
void send_ack(void)
{
PIN_SDA = 0;
delay_us(1);
PIN_SCL = 1;
delay_us(1);
PIN_SCL = 0;
delay_us(1);
}
bool get_ack(void)
{
PIN_SDA_DIR = 1;
delay_us(1);
OED = 0xFE;
PIN_SCL = 1;
delay_us(1);
bool ack = PIN_SDA;
PIN_SCL = 0;
delay_us(1);
OED = 0xFF;
PIN_SDA_DIR = 0;
delay_us(1);
return ack;
}
/* here address(8 bits) = adr (7 bits) + type (1 bit) */
uint8_t get_address(uint8_t adr, uint8_t rdwr)
{
adr &= 0x7F;
adr = adr << 1;
adr |= (rdwr & 0x01);
return adr;
}
/* here send bit after bit and clocking scl with each bit */
void send_byte(uint8_t input)
{
for (uint8_t i = 0; i < 8; i++) {
if ((input & 0x80)) {
PIN_SDA = 1;
delay_us(1);
clock_cd();
} else {
PIN_SDA = 0;
delay_us(1);
clock_cd();
}
input = input << 1;
}
}
/* here receive bit after bit and clocking scl with each bit */
uint8_t receive_byte(void)
{
PIN_SDA_DIR = 1; //FX2 <-- FPGA
OED = 0xFE;
uint8_t input = 0x00;
for (uint8_t i = 0; i < 8; i++) {
PIN_SCL = 1;
delay_us(1);
input = input << 1;
if (PIN_SDA == 1)
input |= 0x01;
else
input |= 0X00;
PIN_SCL = 0;
delay_us(1);
}
OED = 0xFF;
PIN_SDA_DIR = 0;
return input;
}

View File

@ -139,15 +139,12 @@ bool execute_command(void)
payload_index_in += usb_in_bytecount; payload_index_in += usb_in_bytecount;
/* Determine if this was the last command */ /* Determine if this was the last command */
if ((cmd_id_index + usb_out_bytecount + 1) >= EP1OUTBC) { if ((cmd_id_index + usb_out_bytecount + 1) >= EP1OUTBC)
return true; return true;
/* Line between return and else required by checkpatch: */
uint8_t a = 0; /* Not the last command, update cmd_id_index */
} else { cmd_id_index += (usb_out_bytecount + 1);
/* Not the last command, update cmd_id_index */ return false;
cmd_id_index += (usb_out_bytecount + 1);
return false;
}
} }
/** /**

View File

@ -18,6 +18,7 @@
#include <fx2macros.h> #include <fx2macros.h>
#include <serial.h> #include <serial.h>
#include <stdio.h> #include <stdio.h>
#include "i2c.h"
/* Also update external declarations in "include/usb.h" if making changes to /* Also update external declarations in "include/usb.h" if making changes to
* these variables! * these variables!
@ -36,9 +37,9 @@ __code struct usb_device_descriptor device_descriptor = {
.blength = sizeof(struct usb_device_descriptor), .blength = sizeof(struct usb_device_descriptor),
.bdescriptortype = DESCRIPTOR_TYPE_DEVICE, .bdescriptortype = DESCRIPTOR_TYPE_DEVICE,
.bcdusb = 0x0200, /* BCD: 02.00 (Version 2.0 USB spec) */ .bcdusb = 0x0200, /* BCD: 02.00 (Version 2.0 USB spec) */
.bdeviceclass = 0xFF, /* 0xFF = vendor-specific */ .bdeviceclass = 0xEF,
.bdevicesubclass = 0xFF, .bdevicesubclass = 0x02,
.bdeviceprotocol = 0xFF, .bdeviceprotocol = 0x01,
.bmaxpacketsize0 = 64, .bmaxpacketsize0 = 64,
.idvendor = 0x584e, .idvendor = 0x584e,
.idproduct = 0x424e, .idproduct = 0x424e,
@ -55,25 +56,36 @@ __code struct usb_config_descriptor config_descriptor = {
.blength = sizeof(struct usb_config_descriptor), .blength = sizeof(struct usb_config_descriptor),
.bdescriptortype = DESCRIPTOR_TYPE_CONFIGURATION, .bdescriptortype = DESCRIPTOR_TYPE_CONFIGURATION,
.wtotallength = sizeof(struct usb_config_descriptor) + .wtotallength = sizeof(struct usb_config_descriptor) +
sizeof(struct usb_interface_descriptor) + 3 * sizeof(struct usb_interface_descriptor) +
(NUM_ENDPOINTS * sizeof(struct usb_endpoint_descriptor)), ((NUM_ENDPOINTS + 2) * sizeof(struct usb_endpoint_descriptor)),
.bnuminterfaces = 1, .bnuminterfaces = 2,
.bconfigurationvalue = 1, .bconfigurationvalue = 1,
.iconfiguration = 4, /* String describing this configuration */ .iconfiguration = 1, /* String describing this configuration */
.bmattributes = 0x80, /* Only MSB set according to USB spec */ .bmattributes = 0x80, /* Only MSB set according to USB spec */
.maxpower = 50 /* 100 mA */ .maxpower = 50 /* 100 mA */
}; };
__code struct usb_interface_association_descriptor interface_association_descriptor = {
.blength = sizeof(struct usb_interface_association_descriptor),
.bdescriptortype = DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION,
.bfirstinterface = 0x01,
.binterfacecount = 0x02,
.bfunctionclass = 0x02,
.bfunctionsubclass = 0x00,
.bfunctionprotocol = 0x00,
.ifunction = 0x00
};
__code struct usb_interface_descriptor interface_descriptor00 = { __code struct usb_interface_descriptor interface_descriptor00 = {
.blength = sizeof(struct usb_interface_descriptor), .blength = sizeof(struct usb_interface_descriptor),
.bdescriptortype = DESCRIPTOR_TYPE_INTERFACE, .bdescriptortype = DESCRIPTOR_TYPE_INTERFACE,
.binterfacenumber = 0, .binterfacenumber = 0,
.balternatesetting = 0, .balternatesetting = 0,
.bnumendpoints = NUM_ENDPOINTS, .bnumendpoints = NUM_ENDPOINTS,
.binterfaceclass = 0xFF, .binterfaceclass = 0XFF,
.binterfacesubclass = 0xFF, .binterfacesubclass = 0x00,
.binterfaceprotocol = 0xFF, .binterfaceprotocol = 0x00,
.iinterface = 0 .iinterface = 4
}; };
__code struct usb_endpoint_descriptor bulk_ep1_out_endpoint_descriptor = { __code struct usb_endpoint_descriptor bulk_ep1_out_endpoint_descriptor = {
@ -103,16 +115,19 @@ __code struct usb_endpoint_descriptor bulk_ep2_endpoint_descriptor = {
.binterval = 0 .binterval = 0
}; };
__code struct usb_endpoint_descriptor bulk_ep4_endpoint_descriptor = { __code struct usb_interface_descriptor interface_descriptor01 = {
.blength = sizeof(struct usb_endpoint_descriptor), .blength = sizeof(struct usb_interface_descriptor),
.bdescriptortype = 0x05, .bdescriptortype = DESCRIPTOR_TYPE_INTERFACE,
.bendpointaddress = (4 | USB_DIR_IN), .binterfacenumber = 1,
.bmattributes = 0x02, .balternatesetting = 0,
.wmaxpacketsize = 512, .bnumendpoints = 2,
.binterval = 0 .binterfaceclass = 0x0A,
.binterfacesubclass = 0x00,
.binterfaceprotocol = 0x00,
.iinterface = 0x00
}; };
__code struct usb_endpoint_descriptor bulk_ep6_endpoint_descriptor = { __code struct usb_endpoint_descriptor bulk_ep6_out_endpoint_descriptor = {
.blength = sizeof(struct usb_endpoint_descriptor), .blength = sizeof(struct usb_endpoint_descriptor),
.bdescriptortype = 0x05, .bdescriptortype = 0x05,
.bendpointaddress = (6 | USB_DIR_OUT), .bendpointaddress = (6 | USB_DIR_OUT),
@ -121,19 +136,18 @@ __code struct usb_endpoint_descriptor bulk_ep6_endpoint_descriptor = {
.binterval = 0 .binterval = 0
}; };
__code struct usb_endpoint_descriptor bulk_ep8_endpoint_descriptor = { __code struct usb_endpoint_descriptor bulk_ep8_in_endpoint_descriptor = {
.blength = sizeof(struct usb_endpoint_descriptor), .blength = sizeof(struct usb_endpoint_descriptor),
.bdescriptortype = 0x05, .bdescriptortype = 0x05,
.bendpointaddress = (8 | USB_DIR_OUT), .bendpointaddress = (8 | USB_DIR_IN),
.bmattributes = 0x02, .bmattributes = 0x02,
.wmaxpacketsize = 512, .wmaxpacketsize = 512,
.binterval = 0 .binterval = 0
}; };
__code struct usb_language_descriptor language_descriptor = { __code struct usb_language_descriptor language_descriptor = {
.blength = 4, .blength = 4,
.bdescriptortype = DESCRIPTOR_TYPE_STRING, .bdescriptortype = DESCRIPTOR_TYPE_STRING,
.wlangid = {0x0409 /* US English */} .wlangid = {0x0409} /* US English */
}; };
__code struct usb_string_descriptor strmanufacturer = __code struct usb_string_descriptor strmanufacturer =
@ -212,9 +226,15 @@ void ep4_isr(void)__interrupt EP4_ISR
} }
void ep6_isr(void)__interrupt EP6_ISR void ep6_isr(void)__interrupt EP6_ISR
{ {
i2c_recieve();
EXIF &= ~0x10; /* Clear USBINT: Main global interrupt */
EPIRQ = 0x40; /* Clear individual EP6OUT IRQ */
} }
void ep8_isr(void)__interrupt EP8_ISR void ep8_isr(void)__interrupt EP8_ISR
{ {
EXIF &= ~0x10; /* Clear USBINT: Main global interrupt */
EPIRQ = 0x80; /* Clear individual EP8IN IRQ */
} }
void ibn_isr(void)__interrupt IBN_ISR void ibn_isr(void)__interrupt IBN_ISR
{ {
@ -411,21 +431,21 @@ bool usb_handle_clear_feature(void)
switch (setup_data.bmrequesttype) { switch (setup_data.bmrequesttype) {
case CF_DEVICE: case CF_DEVICE:
/* Clear remote wakeup not supported: stall EP0 */ /* Clear remote wakeup not supported: stall EP0 */
STALL_EP0(); STALL_EP0();
break; break;
case CF_ENDPOINT: case CF_ENDPOINT:
if (setup_data.wvalue == 0) { if (setup_data.wvalue == 0) {
/* Unstall the endpoint specified in wIndex */ /* Unstall the endpoint specified in wIndex */
ep_cs = usb_get_endpoint_cs_reg(setup_data.windex); ep_cs = usb_get_endpoint_cs_reg(setup_data.windex);
if (!ep_cs) if (!ep_cs)
return false; return false;
*ep_cs &= ~EPSTALL; *ep_cs &= ~EPSTALL;
} else { } else {
/* Unsupported feature, stall EP0 */ /* Unsupported feature, stall EP0 */
STALL_EP0(); STALL_EP0();
} }
break; break;
default: default:
/* Vendor commands... */ /* Vendor commands... */
break; break;
} }
@ -597,7 +617,6 @@ bool usb_handle_send_bitstream(void)
/* wait until GPIF transaction has been completed */ /* wait until GPIF transaction has been completed */
while ((GPIFTRIG & BMGPIFDONE) == 0) { while ((GPIFTRIG & BMGPIFDONE) == 0) {
if (ix-- == 0) { if (ix-- == 0) {
printf("GPIF done time out\n");
break; break;
} }
delay_ms(1); delay_ms(1);
@ -697,9 +716,9 @@ void ep_init(void)
syncdelay(3); syncdelay(3);
EP4CFG = 0x00; EP4CFG = 0x00;
syncdelay(3); syncdelay(3);
EP6CFG = 0x00; EP6CFG = 0xA2;
syncdelay(3); syncdelay(3);
EP8CFG = 0x00; EP8CFG = 0xE2;
syncdelay(3); syncdelay(3);
/* arm EP1-OUT */ /* arm EP1-OUT */
@ -714,6 +733,12 @@ void ep_init(void)
EP1INBC = 0; EP1INBC = 0;
syncdelay(3); syncdelay(3);
/* arm EP6-OUT */
EP6BCL = 0x80;
syncdelay(3);
EP6BCL = 0x80;
syncdelay(3);
/* Standard procedure to reset FIFOs */ /* Standard procedure to reset FIFOs */
FIFORESET = BMNAKALL; /* NAK all transfers during the reset */ FIFORESET = BMNAKALL; /* NAK all transfers during the reset */
syncdelay(3); syncdelay(3);
@ -727,9 +752,110 @@ void ep_init(void)
syncdelay(3); syncdelay(3);
} }
void i2c_recieve(void)
{
PIN_SDA_DIR = 0;
if (EP6FIFOBUF[0] == 1) {
uint8_t rdwr = EP6FIFOBUF[0]; //read
uint8_t reg_adr_check = EP6FIFOBUF[1];
uint8_t count = EP6FIFOBUF[2]; //request data count
uint8_t adr = EP6FIFOBUF[3]; //address
uint8_t reg_adr = EP6FIFOBUF[4];
uint8_t address = get_address(adr, rdwr); //address byte (read command)
uint8_t address_2 = get_address(adr, 0); //address byte 2 (write command)
printf("%d\n", address);
/* start: */
start_cd();
/* address: */
send_byte(address_2); //write
/* ack: */
uint8_t ack = get_ack();
delay_us(10);
/* send data */
if (reg_adr_check) { //if there is a byte reg
send_byte(reg_adr);
/* ack(): */
ack = get_ack();
}
delay_us(10);
/* repeated start: */
repeated_start();
/* address: */
send_byte(address);
/* get ack: */
ack = get_ack();
delay_us(10);
/* receive data */
for (uint8_t i = 0; i < count; i++) {
EP8FIFOBUF[i] = receive_byte();
/* send ack: */
send_ack();
}
delay_ms(1);
/* stop */
stop_cd();
delay_us(10);
EP8BCH = 0; //EP8
syncdelay(3);
EP8BCL = count; //EP8
EP6BCL = 0x80; //EP6
syncdelay(3);
EP6BCL = 0x80; //EP6
} else {
uint8_t rdwr = EP6FIFOBUF[0]; //write
uint8_t count = EP6FIFOBUF[1]; //data count
uint8_t adr = EP6FIFOBUF[2]; //address
uint8_t address = get_address(adr, rdwr); //address byte (read command)
uint8_t ack_cnt = 0;
/* start(): */
start_cd();
/* address: */
send_byte(address); //write
/* ack(): */
if (!get_ack())
ack_cnt++;
/* send data */
for (uint8_t i = 0; i < count; i++) {
send_byte(EP6FIFOBUF[i + 3]);
/* get ack: */
if (!get_ack())
ack_cnt++;
}
/* stop */
stop_cd();
EP8FIFOBUF[0] = ack_cnt;
EP8BCH = 0; //EP8
syncdelay(3);
EP8BCL = 1; //EP8
EP6BCL = 0x80; //EP6
syncdelay(3);
EP6BCL = 0x80; //EP6
}
}
/** /**
* Interrupt initialization. Configures USB interrupts. * Interrupt initialization. Configures USB interrupts.
*/ **/
void interrupt_init(void) void interrupt_init(void)
{ {
/* Enable Interrupts */ /* Enable Interrupts */
@ -742,11 +868,11 @@ void interrupt_init(void)
/* Enable INT 2 & 4 Autovectoring */ /* Enable INT 2 & 4 Autovectoring */
INTSETUP |= (AV2EN | AV4EN); INTSETUP |= (AV2EN | AV4EN);
/* Enable individual EP1OUT&IN interrupts */ /* Enable individual EP1OUT&IN & EP6&8 interrupts */
EPIE |= 0x0C; EPIE |= 0xCC;
/* Clear individual USB interrupt IRQ */ /* Clear individual USB interrupt IRQ */
EPIRQ = 0x0C; EPIRQ = 0xCC;
/* Enable SUDAV interrupt */ /* Enable SUDAV interrupt */
USBIEN |= SUDAVI; USBIEN |= SUDAVI;
@ -777,8 +903,15 @@ void io_init(void)
PIN_TDI = 0; PIN_TDI = 0;
PIN_SRST = 1; PIN_SRST = 1;
/* PORT C */ /* PORT C */
PORTCCFG = 0x00; /* 0: normal ou 1: alternate function (each bit) */ PORTCCFG = 0x00; /* 0: normal ou 1: alternate function (each bit) */
OEC = 0xEF; OEC = 0xFF;
IOC = 0xFF; IOC = 0xFF;
/* PORT D */
OED = 0xFF;
IOD = 0xFF;
PIN_SDA_DIR = 0;
} }

View File

@ -2,7 +2,7 @@
# Copyright (C) 2023 by NanoXplore, France - all rights reserved # Copyright (C) 2023 by NanoXplore, France - all rights reserved
# Needed by timing test # Needed by timing test
export PROJECT := angie_openocd export PROJECT := angie_bitstream
TARGET_PART := xc6slx9-2tqg144 TARGET_PART := xc6slx9-2tqg144
export TOPLEVEL := S609 export TOPLEVEL := S609

View File

@ -14,17 +14,31 @@ net TRST LOC = 'P48' ;
net TMS LOC = 'P43' ; net TMS LOC = 'P43' ;
net TCK LOC = 'P44' ; net TCK LOC = 'P44' ;
net TDI LOC = 'P45' ; net TDI LOC = 'P45' ;
net TDO LOC = 'P46' ; net TDO LOC = 'P46' ;
net SRST LOC = 'P61' ; net SRST LOC = 'P61' ;
net SDA LOC = 'P50' ;
net SCL LOC = 'P51' ;
net SDA_DIR LOC = 'P56' ;
net SI_TDO LOC = 'P16' ; net SI_TDO LOC = 'P16' ;
net SO_TRST LOC = 'P32' ; net SO_TRST LOC = 'P32' ;
net SO_TMS LOC = 'P27' ; net SO_TMS LOC = 'P27' ;
net SO_TCK LOC = 'P30' ; net SO_TCK LOC = 'P30' ;
net SO_TDI LOC = 'P26' ; net SO_TDI LOC = 'P26' ;
net SO_SRST LOC = 'P12' ; net SO_SRST LOC = 'P12' ;
net SO_SDA_OUT LOC = 'P140' ;
net SO_SDA_IN LOC = 'P1' ;
net SO_SCL LOC = 'P137';
net ST_0 LOC = 'P29' ; net ST_0 LOC = 'P29' ;
net ST_1 LOC = 'P21' ; net ST_1 LOC = 'P21' ;
net ST_2 LOC = 'P11' ; net ST_2 LOC = 'P11' ;
net ST_4 LOC = 'P134' ;
net ST_5 LOC = 'P139' ;
net FTP<0> LOC = 'P121' ; net FTP<0> LOC = 'P121' ;
net FTP<1> LOC = 'P120' ; net FTP<1> LOC = 'P120' ;
net FTP<2> LOC = 'P119' ; net FTP<2> LOC = 'P119' ;

View File

@ -16,22 +16,35 @@ library UNISIM;
use UNISIM.VComponents.all; use UNISIM.VComponents.all;
entity S609 is port( entity S609 is port(
TRST : in std_logic; TRST : in std_logic;
TMS : in std_logic; TMS : in std_logic;
TCK : in std_logic; TCK : in std_logic;
TDI : in std_logic; TDI : in std_logic;
TDO : out std_logic; TDO : out std_logic;
SRST : in std_logic; SRST : in std_logic;
FTP : out std_logic_vector(7 downto 0); -- Test points
SDA : inout std_logic;
SDA_DIR : in std_logic;
SCL : in std_logic;
FTP : out std_logic_vector(7 downto 0):=(others => '1'); -- Test points
SI_TDO : in std_logic; SI_TDO : in std_logic;
ST_0 : out std_logic; ST_0 : out std_logic;
ST_1 : out std_logic; ST_1 : out std_logic;
ST_2 : out std_logic; ST_2 : out std_logic;
ST_4 : out std_logic;
ST_5 : out std_logic;
SO_SDA_OUT : out std_logic;
SO_SDA_IN : in std_logic;
SO_SCL : out std_logic;
SO_TRST : out std_logic; SO_TRST : out std_logic;
SO_TMS : out std_logic; SO_TMS : out std_logic;
SO_TCK : out std_logic; SO_TCK : out std_logic;
SO_TDI : out std_logic; SO_TDI : out std_logic;
SO_SRST :out std_logic SO_SRST : out std_logic
); );
end S609; end S609;
@ -42,6 +55,8 @@ begin
ST_0 <= '0'; ST_0 <= '0';
ST_1 <= '1'; ST_1 <= '1';
ST_4 <= '0';
--TDO: --TDO:
TDO <= not SI_TDO; TDO <= not SI_TDO;
@ -53,11 +68,26 @@ SO_TDI <= TDI;
ST_2 <= SRST; ST_2 <= SRST;
SO_SRST <= '0'; SO_SRST <= '0';
SO_SCL <= SCL;
SDA <= not(SO_SDA_IN) when (SDA_DIR = '1') else 'Z';
SO_SDA_OUT <= SDA;
process(SDA_DIR)
begin
if(SDA_DIR = '1') then
ST_5 <= '1';
else
ST_5 <= '0';
end if;
end process;
--Points de test: --Points de test:
FTP(0) <= TRST; FTP(0) <= SDA;
FTP(1) <= TMS; FTP(1) <= SCL;
FTP(2) <= TCK; FTP(2) <= not(SO_SDA_IN);
FTP(3) <= TDI; FTP(3) <= SDA_DIR;
FTP(5) <= SRST; FTP(5) <= SRST;
FTP(4) <= SI_TDO; FTP(4) <= SI_TDO;
FTP(6) <= '1'; FTP(6) <= '1';

View File

@ -1,13 +1,13 @@
# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later # 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 Bus 001 Device 029: ID 584e:424e NanoXplore, SAS. ANGIE Adapter
Device Descriptor: Device Descriptor:
bLength 18 bLength 18
bDescriptorType 1 bDescriptorType 1
bcdUSB 2.00 bcdUSB 2.00
bDeviceClass 255 Vendor Specific Class bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 255 Vendor Specific Subclass bDeviceSubClass 2
bDeviceProtocol 255 Vendor Specific Protocol bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64 bMaxPacketSize0 64
idVendor 0x584e idVendor 0x584e
idProduct 0x424e idProduct 0x424e
@ -19,13 +19,22 @@ Device Descriptor:
Configuration Descriptor: Configuration Descriptor:
bLength 9 bLength 9
bDescriptorType 2 bDescriptorType 2
wTotalLength 0x0027 wTotalLength 0x0047
bNumInterfaces 1 bNumInterfaces 2
bConfigurationValue 1 bConfigurationValue 1
iConfiguration 4 (error) iConfiguration 1 NanoXplore, SAS.
bmAttributes 0x80 bmAttributes 0x80
(Bus Powered) (Bus Powered)
MaxPower 100mA MaxPower 100mA
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 1
bInterfaceCount 2
bFunctionClass 2 Communications
bFunctionSubClass 0
bFunctionProtocol 0
iFunction 0
Interface Descriptor: Interface Descriptor:
bLength 9 bLength 9
bDescriptorType 4 bDescriptorType 4
@ -33,9 +42,9 @@ Device Descriptor:
bAlternateSetting 0 bAlternateSetting 0
bNumEndpoints 3 bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass bInterfaceSubClass 0
bInterfaceProtocol 255 Vendor Specific Protocol bInterfaceProtocol 0
iInterface 0 iInterface 4 JTAG Adapter
Endpoint Descriptor: Endpoint Descriptor:
bLength 7 bLength 7
bDescriptorType 5 bDescriptorType 5
@ -66,3 +75,33 @@ Device Descriptor:
Usage Type Data Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0 bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x06 EP 6 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x88 EP 8 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0