aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorAhmed BOUDJELIDA <aboudjelida@nanoxplore.com>2023-08-16 17:05:05 +0200
committerAntonio Borneo <borneo.antonio@gmail.com>2023-08-26 11:45:43 +0000
commitaee495e7859d0f19b52ba12cafaad2628d84f8e1 (patch)
tree0b98216ee50f81938e23238e5098e064026553b0 /contrib
parentaa0056d27355d7719a120cdc4292215acae40819 (diff)
downloadriscv-openocd-aee495e7859d0f19b52ba12cafaad2628d84f8e1.zip
riscv-openocd-aee495e7859d0f19b52ba12cafaad2628d84f8e1.tar.gz
riscv-openocd-aee495e7859d0f19b52ba12cafaad2628d84f8e1.tar.bz2
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>
Diffstat (limited to 'contrib')
-rw-r--r--contrib/firmware/angie/c/Makefile7
-rw-r--r--contrib/firmware/angie/c/README4
-rw-r--r--contrib/firmware/angie/c/include/i2c.h28
-rw-r--r--contrib/firmware/angie/c/include/io.h16
-rw-r--r--contrib/firmware/angie/c/include/usb.h120
-rw-r--r--contrib/firmware/angie/c/src/i2c.c127
-rw-r--r--contrib/firmware/angie/c/src/protocol.c13
-rw-r--r--contrib/firmware/angie/c/src/usb.c217
-rw-r--r--contrib/firmware/angie/hdl/Makefile2
-rw-r--r--contrib/firmware/angie/hdl/src/angie_bitstream.ucf (renamed from contrib/firmware/angie/hdl/src/angie_openocd.ucf)16
-rw-r--r--contrib/firmware/angie/hdl/src/angie_bitstream.vhd (renamed from contrib/firmware/angie/hdl/src/angie_openocd.vhd)64
11 files changed, 485 insertions, 129 deletions
diff --git a/contrib/firmware/angie/c/Makefile b/contrib/firmware/angie/c/Makefile
index 80e8cbe..e919cd0 100644
--- a/contrib/firmware/angie/c/Makefile
+++ b/contrib/firmware/angie/c/Makefile
@@ -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
# 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 \
$(INCLUDE_DIR)/protocol.h \
$(INCLUDE_DIR)/jtag.h \
@@ -47,7 +47,8 @@ HEADERS = $(INCLUDE_DIR)/usb.h \
$(INCLUDE_DIR)/io.h \
$(INCLUDE_DIR)/serial.h \
$(INCLUDE_DIR)/fx2macros.h \
- $(INCLUDE_DIR)/msgtypes.h
+ $(INCLUDE_DIR)/msgtypes.h \
+ $(INCLUDE_DIR)/i2c.h
# Disable all built-in rules.
.SUFFIXES:
@@ -61,7 +62,7 @@ all: 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.
+# Rebuild every C module (there are only 8 of them) if any header changes.
%.rel: $(SRC_DIR)/%.c $(HEADERS)
$(CC) -c $(CFLAGS) -mmcs51 -I$(INCLUDE_DIR) -o $@ $<
diff --git a/contrib/firmware/angie/c/README b/contrib/firmware/angie/c/README
index 04ed0be..2d41da7 100644
--- a/contrib/firmware/angie/c/README
+++ b/contrib/firmware/angie/c/README
@@ -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
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
+Simply type "make bin" in the ANGIE directory to compile the firmware.
+"make clean" will remove all generated files except the BIN file
required for downloading the firmware to ANGIE.
Note that the EZ-USB FX2 microcontroller does not have on-chip flash,
diff --git a/contrib/firmware/angie/c/include/i2c.h b/contrib/firmware/angie/c/include/i2c.h
new file mode 100644
index 0000000..06185ef
--- /dev/null
+++ b/contrib/firmware/angie/c/include/i2c.h
@@ -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
diff --git a/contrib/firmware/angie/c/include/io.h b/contrib/firmware/angie/c/include/io.h
index 35afa62..af488f4 100644
--- a/contrib/firmware/angie/c/include/io.h
+++ b/contrib/firmware/angie/c/include/io.h
@@ -45,14 +45,14 @@
#define PIN_TDI IOB3
#define PIN_TDO IOB4
#define PIN_SRST IOB5
-/* PA6 Not Connected */
-/* PA7 Not Connected */
+/* PB6 Not Connected */
+/* PB7 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:
+/* PORT C */
#define PIN_T0 IOC0
#define PIN_T1 IOC1
#define PIN_T2 IOC2
@@ -62,4 +62,14 @@
/* PC6 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
diff --git a/contrib/firmware/angie/c/include/usb.h b/contrib/firmware/angie/c/include/usb.h
index 0450d1d..07cb12a 100644
--- a/contrib/firmware/angie/c/include/usb.h
+++ b/contrib/firmware/angie/c/include/usb.h
@@ -24,18 +24,19 @@
#define STALL_EP0() (EP0CS |= EPSTALL)
#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 */
-#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
+/* USB Descriptor Types. See USB 2.0 Spec */
+#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 DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION 0x0B
#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 {
uint8_t blength; /**< Size of this descriptor in bytes. */
uint8_t bdescriptortype; /**< DEVICE Descriptor Type. */
@@ -53,7 +54,7 @@ struct usb_device_descriptor {
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 {
uint8_t blength; /**< Size of this descriptor in bytes. */
uint8_t bdescriptortype; /**< CONFIGURATION descriptor type. */
@@ -65,7 +66,19 @@ struct usb_config_descriptor {
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 {
uint8_t blength; /**< Size of this descriptor in bytes. */
uint8_t bdescriptortype; /**< INTERFACE descriptor type. */
@@ -78,7 +91,7 @@ struct usb_interface_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 {
uint8_t blength; /**< Size of this descriptor in bytes. */
uint8_t bdescriptortype; /**< ENDPOINT descriptor type. */
@@ -88,14 +101,14 @@ struct usb_endpoint_descriptor {
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 {
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 */
+/** USB String Descriptor. See USB 2.0 Spec */
struct usb_string_descriptor {
uint8_t blength; /**< Size of this descriptor in bytes. */
uint8_t bdescriptortype; /**< STRING descriptor type. */
@@ -104,7 +117,7 @@ struct usb_string_descriptor {
/********************** 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 {
uint8_t bmrequesttype; /**< Characteristics of a 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;
/*
- * 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
- * 0 = Host-to-device
- * 1 = Device-to-host
+ * 0 = Host-to-device
+ * 1 = Device-to-host
* Bit 6...5: Type
- * 0 = Standard
- * 1 = Class
- * 2 = Vendor
- * 3 = Reserved
+ * 0 = Standard
+ * 1 = Class
+ * 2 = Vendor
+ * 3 = Reserved
* Bit 4...0: Recipient
- * 0 = Device
- * 1 = Interface
- * 2 = Endpoint
- * 3 = Other
- * 4...31 = Reserved
+ * 0 = Device
+ * 1 = Interface
+ * 2 = Endpoint
+ * 3 = Other
+ * 4...31 = Reserved
*/
-#define USB_DIR_OUT 0x00
-#define USB_DIR_IN 0x80
+#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
+#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_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)
+#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)
+#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_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)
+#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)
+#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_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)
@@ -190,27 +203,27 @@ extern volatile __xdata __at 0xE6B8 struct setup_data setup_data;
/* 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
+/* USB Requests (bRequest): See USB 2.0 Spec */
+#define GET_STATUS 0
+#define CLEAR_FEATURE 1
/* Value '2' is reserved for future use */
-#define SET_FEATURE 3
+#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 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
+/* Standard Feature Selectors: See USB 2.0 Spec */
+#define DEVICE_REMOTE_WAKEUP 1
+#define ENDPOINT_HALT 0
/************************** 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 {
SUDAV_ISR = 13,
SOF_ISR,
@@ -265,7 +278,10 @@ bool usb_handle_set_feature(void);
bool usb_handle_get_descriptor(void);
void usb_handle_set_interface(void);
void usb_handle_setup_data(void);
+void usb_handle_i2c_in(void);
+void usb_handle_i2c_out(void);
+void i2c_recieve(void);
void ep_init(void);
void interrupt_init(void);
void io_init(void);
diff --git a/contrib/firmware/angie/c/src/i2c.c b/contrib/firmware/angie/c/src/i2c.c
new file mode 100644
index 0000000..a7004bf
--- /dev/null
+++ b/contrib/firmware/angie/c/src/i2c.c
@@ -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;
+}
diff --git a/contrib/firmware/angie/c/src/protocol.c b/contrib/firmware/angie/c/src/protocol.c
index 3f3aaaf..d84534b 100644
--- a/contrib/firmware/angie/c/src/protocol.c
+++ b/contrib/firmware/angie/c/src/protocol.c
@@ -139,15 +139,12 @@ bool execute_command(void)
payload_index_in += usb_in_bytecount;
/* 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;
- /* 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;
- }
+
+ /* Not the last command, update cmd_id_index */
+ cmd_id_index += (usb_out_bytecount + 1);
+ return false;
}
/**
diff --git a/contrib/firmware/angie/c/src/usb.c b/contrib/firmware/angie/c/src/usb.c
index 8fd4de6..747fef1 100644
--- a/contrib/firmware/angie/c/src/usb.c
+++ b/contrib/firmware/angie/c/src/usb.c
@@ -18,6 +18,7 @@
#include <fx2macros.h>
#include <serial.h>
#include <stdio.h>
+#include "i2c.h"
/* Also update external declarations in "include/usb.h" if making changes to
* these variables!
@@ -36,9 +37,9 @@ __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,
+ .bdeviceclass = 0xEF,
+ .bdevicesubclass = 0x02,
+ .bdeviceprotocol = 0x01,
.bmaxpacketsize0 = 64,
.idvendor = 0x584e,
.idproduct = 0x424e,
@@ -55,25 +56,36 @@ __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,
+ 3 * sizeof(struct usb_interface_descriptor) +
+ ((NUM_ENDPOINTS + 2) * sizeof(struct usb_endpoint_descriptor)),
+ .bnuminterfaces = 2,
.bconfigurationvalue = 1,
- .iconfiguration = 4, /* String describing this configuration */
+ .iconfiguration = 1, /* String describing this configuration */
.bmattributes = 0x80, /* Only MSB set according to USB spec */
.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 = {
.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
+ .binterfaceclass = 0XFF,
+ .binterfacesubclass = 0x00,
+ .binterfaceprotocol = 0x00,
+ .iinterface = 4
};
__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
};
-__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_interface_descriptor interface_descriptor01 = {
+ .blength = sizeof(struct usb_interface_descriptor),
+ .bdescriptortype = DESCRIPTOR_TYPE_INTERFACE,
+ .binterfacenumber = 1,
+ .balternatesetting = 0,
+ .bnumendpoints = 2,
+ .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),
.bdescriptortype = 0x05,
.bendpointaddress = (6 | USB_DIR_OUT),
@@ -121,19 +136,18 @@ __code struct usb_endpoint_descriptor bulk_ep6_endpoint_descriptor = {
.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),
.bdescriptortype = 0x05,
- .bendpointaddress = (8 | USB_DIR_OUT),
+ .bendpointaddress = (8 | USB_DIR_IN),
.bmattributes = 0x02,
.wmaxpacketsize = 512,
.binterval = 0
};
-
__code struct usb_language_descriptor language_descriptor = {
.blength = 4,
.bdescriptortype = DESCRIPTOR_TYPE_STRING,
- .wlangid = {0x0409 /* US English */}
+ .wlangid = {0x0409} /* US English */
};
__code struct usb_string_descriptor strmanufacturer =
@@ -212,9 +226,15 @@ void ep4_isr(void)__interrupt EP4_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
{
+ EXIF &= ~0x10; /* Clear USBINT: Main global interrupt */
+ EPIRQ = 0x80; /* Clear individual EP8IN IRQ */
}
void ibn_isr(void)__interrupt IBN_ISR
{
@@ -411,21 +431,21 @@ bool usb_handle_clear_feature(void)
switch (setup_data.bmrequesttype) {
case CF_DEVICE:
/* Clear remote wakeup not supported: stall EP0 */
- STALL_EP0();
- break;
+ STALL_EP0();
+ break;
case CF_ENDPOINT:
- if (setup_data.wvalue == 0) {
+ 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;
+ 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:
+ STALL_EP0();
+ }
+ break;
+ default:
/* Vendor commands... */
break;
}
@@ -597,7 +617,6 @@ bool usb_handle_send_bitstream(void)
/* wait until GPIF transaction has been completed */
while ((GPIFTRIG & BMGPIFDONE) == 0) {
if (ix-- == 0) {
- printf("GPIF done time out\n");
break;
}
delay_ms(1);
@@ -697,9 +716,9 @@ void ep_init(void)
syncdelay(3);
EP4CFG = 0x00;
syncdelay(3);
- EP6CFG = 0x00;
+ EP6CFG = 0xA2;
syncdelay(3);
- EP8CFG = 0x00;
+ EP8CFG = 0xE2;
syncdelay(3);
/* arm EP1-OUT */
@@ -714,6 +733,12 @@ void ep_init(void)
EP1INBC = 0;
syncdelay(3);
+ /* arm EP6-OUT */
+ EP6BCL = 0x80;
+ syncdelay(3);
+ EP6BCL = 0x80;
+ syncdelay(3);
+
/* Standard procedure to reset FIFOs */
FIFORESET = BMNAKALL; /* NAK all transfers during the reset */
syncdelay(3);
@@ -727,9 +752,110 @@ void ep_init(void)
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.
- */
+ **/
void interrupt_init(void)
{
/* Enable Interrupts */
@@ -742,11 +868,11 @@ void interrupt_init(void)
/* Enable INT 2 & 4 Autovectoring */
INTSETUP |= (AV2EN | AV4EN);
- /* Enable individual EP1OUT&IN interrupts */
- EPIE |= 0x0C;
+ /* Enable individual EP1OUT&IN & EP6&8 interrupts */
+ EPIE |= 0xCC;
/* Clear individual USB interrupt IRQ */
- EPIRQ = 0x0C;
+ EPIRQ = 0xCC;
/* Enable SUDAV interrupt */
USBIEN |= SUDAVI;
@@ -777,8 +903,15 @@ void io_init(void)
PIN_TDI = 0;
PIN_SRST = 1;
+
+
/* PORT C */
PORTCCFG = 0x00; /* 0: normal ou 1: alternate function (each bit) */
- OEC = 0xEF;
+ OEC = 0xFF;
IOC = 0xFF;
+
+ /* PORT D */
+ OED = 0xFF;
+ IOD = 0xFF;
+ PIN_SDA_DIR = 0;
}
diff --git a/contrib/firmware/angie/hdl/Makefile b/contrib/firmware/angie/hdl/Makefile
index c2c74a0..b28b650 100644
--- a/contrib/firmware/angie/hdl/Makefile
+++ b/contrib/firmware/angie/hdl/Makefile
@@ -2,7 +2,7 @@
# Copyright (C) 2023 by NanoXplore, France - all rights reserved
# Needed by timing test
-export PROJECT := angie_openocd
+export PROJECT := angie_bitstream
TARGET_PART := xc6slx9-2tqg144
export TOPLEVEL := S609
diff --git a/contrib/firmware/angie/hdl/src/angie_openocd.ucf b/contrib/firmware/angie/hdl/src/angie_bitstream.ucf
index fda3cda..92a89c9 100644
--- a/contrib/firmware/angie/hdl/src/angie_openocd.ucf
+++ b/contrib/firmware/angie/hdl/src/angie_bitstream.ucf
@@ -14,17 +14,31 @@ net TRST LOC = 'P48' ;
net TMS LOC = 'P43' ;
net TCK LOC = 'P44' ;
net TDI LOC = 'P45' ;
-net TDO LOC = 'P46' ;
+net TDO LOC = 'P46' ;
net SRST LOC = 'P61' ;
+
+net SDA LOC = 'P50' ;
+net SCL LOC = 'P51' ;
+net SDA_DIR LOC = 'P56' ;
+
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 SO_SDA_OUT LOC = 'P140' ;
+net SO_SDA_IN LOC = 'P1' ;
+net SO_SCL LOC = 'P137';
+
net ST_0 LOC = 'P29' ;
net ST_1 LOC = 'P21' ;
net ST_2 LOC = 'P11' ;
+
+net ST_4 LOC = 'P134' ;
+net ST_5 LOC = 'P139' ;
+
net FTP<0> LOC = 'P121' ;
net FTP<1> LOC = 'P120' ;
net FTP<2> LOC = 'P119' ;
diff --git a/contrib/firmware/angie/hdl/src/angie_openocd.vhd b/contrib/firmware/angie/hdl/src/angie_bitstream.vhd
index d79c0fe..21ddb84 100644
--- a/contrib/firmware/angie/hdl/src/angie_openocd.vhd
+++ b/contrib/firmware/angie/hdl/src/angie_bitstream.vhd
@@ -16,22 +16,35 @@ 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
+ TRST : in std_logic;
+ TMS : in std_logic;
+ TCK : in std_logic;
+ TDI : in std_logic;
+ TDO : out std_logic;
+ SRST : in std_logic;
+
+ 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;
- ST_0 : out std_logic;
- ST_1 : out std_logic;
- ST_2 : out std_logic;
+ ST_0 : out std_logic;
+ ST_1 : 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_TMS : out std_logic;
- SO_TCK : out std_logic;
+ SO_TMS : out std_logic;
+ SO_TCK : out std_logic;
SO_TDI : out std_logic;
- SO_SRST :out std_logic
+ SO_SRST : out std_logic
);
end S609;
@@ -42,6 +55,8 @@ begin
ST_0 <= '0';
ST_1 <= '1';
+ST_4 <= '0';
+
--TDO:
TDO <= not SI_TDO;
@@ -53,11 +68,26 @@ SO_TDI <= TDI;
ST_2 <= SRST;
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:
-FTP(0) <= TRST;
-FTP(1) <= TMS;
-FTP(2) <= TCK;
-FTP(3) <= TDI;
+FTP(0) <= SDA;
+FTP(1) <= SCL;
+FTP(2) <= not(SO_SDA_IN);
+FTP(3) <= SDA_DIR;
FTP(5) <= SRST;
FTP(4) <= SI_TDO;
FTP(6) <= '1';