From ba860abcab58e244bc4cc14b24cec7a5e8e30069 Mon Sep 17 00:00:00 2001 From: Ahmed BOUDJELIDA Date: Mon, 11 Dec 2023 14:39:57 +0100 Subject: jtag/drivers: Add GPIO extender configuration function to ANGIE driver Add GPIO extender initial configuration that is needed to configure some important GPIOs and ensure that the dev board is ready to work. Add i2c_write function that make a write transfer to any slave device. Give a new Product ID to ANGIE to make it different than the non programmed ANGIE. Change-Id: I0a8dacb7fe218145b7d3ed1cb75f106ed6256714 Signed-off-by: Ahmed BOUDJELIDA Reviewed-on: https://review.openocd.org/c/openocd/+/8072 Tested-by: jenkins Reviewed-by: Antonio Borneo --- contrib/firmware/angie/c/include/usb.h | 1 - contrib/firmware/angie/c/src/usb.c | 11 --- doc/usb_adapters/angie/584e_414f_angie.txt | 98 ++++++++++++++++++++++++ doc/usb_adapters/angie/584e_424e_angie.txt | 107 -------------------------- src/jtag/drivers/angie.c | 118 ++++++++++++++++++++++++++++- src/jtag/drivers/angie/angie_firmware.bin | Bin 10256 -> 10248 bytes 6 files changed, 212 insertions(+), 123 deletions(-) create mode 100644 doc/usb_adapters/angie/584e_414f_angie.txt delete mode 100644 doc/usb_adapters/angie/584e_424e_angie.txt diff --git a/contrib/firmware/angie/c/include/usb.h b/contrib/firmware/angie/c/include/usb.h index 07cb12a..e10947d 100644 --- a/contrib/firmware/angie/c/include/usb.h +++ b/contrib/firmware/angie/c/include/usb.h @@ -32,7 +32,6 @@ #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__ } } diff --git a/contrib/firmware/angie/c/src/usb.c b/contrib/firmware/angie/c/src/usb.c index a1b72e2..a137d3d 100644 --- a/contrib/firmware/angie/c/src/usb.c +++ b/contrib/firmware/angie/c/src/usb.c @@ -65,17 +65,6 @@ __code struct usb_config_descriptor config_descriptor = { .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, diff --git a/doc/usb_adapters/angie/584e_414f_angie.txt b/doc/usb_adapters/angie/584e_414f_angie.txt new file mode 100644 index 0000000..6c25f43 --- /dev/null +++ b/doc/usb_adapters/angie/584e_414f_angie.txt @@ -0,0 +1,98 @@ +# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later + +Bus 002 Device 105: ID 584e:414f NanoXplore, SAS. ANGIE Adapter +Device Descriptor: + bLength 18 + bDescriptorType 1 + bcdUSB 2.00 + bDeviceClass 239 Miscellaneous Device + bDeviceSubClass 2 + bDeviceProtocol 1 Interface Association + bMaxPacketSize0 64 + idVendor 0x584e + idProduct 0x414f + bcdDevice 0.00 + iManufacturer 1 NanoXplore, SAS. + iProduct 2 ANGIE Adapter + iSerial 3 000001 + bNumConfigurations 1 + Configuration Descriptor: + bLength 9 + bDescriptorType 2 + wTotalLength 0x0047 + bNumInterfaces 2 + bConfigurationValue 1 + iConfiguration 1 NanoXplore, SAS. + bmAttributes 0x80 + (Bus Powered) + MaxPower 100mA + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 0 + bAlternateSetting 0 + bNumEndpoints 3 + bInterfaceClass 255 Vendor Specific Class + bInterfaceSubClass 0 + bInterfaceProtocol 0 + iInterface 4 JTAG Adapter + 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 + 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 diff --git a/doc/usb_adapters/angie/584e_424e_angie.txt b/doc/usb_adapters/angie/584e_424e_angie.txt deleted file mode 100644 index d68657a..0000000 --- a/doc/usb_adapters/angie/584e_424e_angie.txt +++ /dev/null @@ -1,107 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later - -Bus 001 Device 029: ID 584e:424e NanoXplore, SAS. ANGIE Adapter -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 2.00 - bDeviceClass 239 Miscellaneous Device - bDeviceSubClass 2 - bDeviceProtocol 1 Interface Association - 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 0x0047 - bNumInterfaces 2 - bConfigurationValue 1 - iConfiguration 1 NanoXplore, SAS. - bmAttributes 0x80 - (Bus Powered) - MaxPower 100mA - Interface Association: - bLength 8 - bDescriptorType 11 - bFirstInterface 1 - bInterfaceCount 2 - bFunctionClass 2 Communications - bFunctionSubClass 0 - bFunctionProtocol 0 - iFunction 0 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 3 - bInterfaceClass 255 Vendor Specific Class - bInterfaceSubClass 0 - bInterfaceProtocol 0 - iInterface 4 JTAG Adapter - 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 - 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 diff --git a/src/jtag/drivers/angie.c b/src/jtag/drivers/angie.c index d4219d3..dfe65a2 100644 --- a/src/jtag/drivers/angie.c +++ b/src/jtag/drivers/angie.c @@ -167,7 +167,8 @@ static int angie_load_firmware_and_renumerate(struct angie *device, const char * uint32_t delay_us); static int angie_load_firmware(struct angie *device, const char *filename); static int angie_load_bitstream(struct angie *device, const char *filename); - +static int angie_i2c_write(struct angie *device, uint8_t *i2c_data, uint8_t i2c_data_size); +static void angie_io_extender_config(struct angie *device, uint8_t i2c_adr, uint8_t cfg_value, uint8_t value); static int angie_write_firmware_section(struct angie *device, struct image *firmware_image, int section_index); @@ -338,7 +339,15 @@ static int angie_load_firmware_and_renumerate(struct angie *device, usleep(delay_us); - return angie_usb_open(device); + ret = angie_usb_open(device); + if (ret != ERROR_OK) + return ret; + + ret = libusb_claim_interface(angie_handle->usb_device_handle, 0); + if (ret != LIBUSB_SUCCESS) + return ERROR_FAIL; + + return ERROR_OK; } /** @@ -476,6 +485,72 @@ static int angie_load_bitstream(struct angie *device, const char *filename) } /** + * Send an i2c write operation to dev-board components. + * + * @param device pointer to struct angie identifying ANGIE driver instance. + * @param i2c_data table of i2c data that we want to write to slave device. + * @param i2c_data_size the size of i2c data table. + * @return on success: ERROR_OK + * @return on failure: ERROR_FAIL + */ +static int angie_i2c_write(struct angie *device, uint8_t *i2c_data, uint8_t i2c_data_size) +{ + char i2c_data_buffer[i2c_data_size + 2]; + char buffer_received[1]; + int ret, transferred; + i2c_data_buffer[0] = 0; // write = 0 + i2c_data_buffer[1] = i2c_data_size - 1; // i2c_data count (without address) + + for (uint8_t i = 0; i < i2c_data_size; i++) + i2c_data_buffer[i + 2] = i2c_data[i]; + + // Send i2c packet to Dev-board and configure its clock source / + ret = jtag_libusb_bulk_write(device->usb_device_handle, 0x06, i2c_data_buffer, + i2c_data_size + 2, 1000, &transferred); + if (ret != ERROR_OK) { + LOG_ERROR("Error in i2c clock gen configuration : ret ERROR"); + angie_quit(); + return ret; + } + if (transferred != i2c_data_size + 2) { + LOG_ERROR("Error in i2c clock gen configuration : bytes transferred"); + angie_quit(); + return ERROR_FAIL; + } + + usleep(500); + + // Receive packet from ANGIE / + ret = jtag_libusb_bulk_write(device->usb_device_handle, 0x88, buffer_received, 1, 1000, &transferred); + if (ret != ERROR_OK) { + LOG_ERROR("Error in i2c clock gen configuration : ret ERROR"); + angie_quit(); + return ret; + } + return ERROR_OK; +} + +/** + * Configure dev-board gpio extender modules by configuring their + * register 3 and register 1 responsible for IO directions and values. + * + * @param device pointer to struct angie identifying ANGIE driver instance. + * @param i2c_adr i2c address of the gpio extender. + * @param cfg_value IOs configuration to be written in register Number 3. + * @param value the IOs value to be written in register Number 1. + * @return on success: ERROR_OK + * @return on failure: ERROR_FAIL + */ +static void angie_io_extender_config(struct angie *device, uint8_t i2c_adr, uint8_t cfg_value, uint8_t value) +{ + uint8_t ioconfig[3] = {i2c_adr, 3, cfg_value}; + angie_i2c_write(device, ioconfig, 3); + uint8_t iovalue[3] = {i2c_adr, 1, value}; + angie_i2c_write(device, iovalue, 3); + usleep(500); +} + +/** * Send one contiguous firmware section to the ANGIE's EZ-USB microcontroller * over the USB bus. * @@ -2175,7 +2250,7 @@ static int angie_init(void) if (download_firmware) { LOG_INFO("Loading ANGIE firmware. This is reversible by power-cycling ANGIE device."); - if (libusb_claim_interface(angie_handle->usb_device_handle, 0) != ERROR_OK) + if (libusb_claim_interface(angie_handle->usb_device_handle, 0) != LIBUSB_SUCCESS) LOG_ERROR("Could not claim interface"); ret = angie_load_firmware_and_renumerate(angie_handle, @@ -2191,14 +2266,49 @@ static int angie_init(void) angie_quit(); return ret; } + if (libusb_claim_interface(angie_handle->usb_device_handle, 1) != LIBUSB_SUCCESS) { + LOG_ERROR("Could not claim interface 1"); + angie_quit(); + return ERROR_FAIL; + } + angie_io_extender_config(angie_handle, 0x22, 0xFF, 0xFF); + if (ret != ERROR_OK) { + LOG_ERROR("Could not configure io extender 22"); + angie_quit(); + return ret; + } + angie_io_extender_config(angie_handle, 0x23, 0xFF, 0xFF); + if (ret != ERROR_OK) { + LOG_ERROR("Could not configure io extender 23"); + angie_quit(); + return ret; + } + angie_io_extender_config(angie_handle, 0x24, 0x1F, 0x9F); + if (ret != ERROR_OK) { + LOG_ERROR("Could not configure io extender 24"); + angie_quit(); + return ret; + } + angie_io_extender_config(angie_handle, 0x25, 0x07, 0x00); + if (ret != ERROR_OK) { + LOG_ERROR("Could not configure io extender 25"); + angie_quit(); + return ret; + } + if (libusb_release_interface(angie_handle->usb_device_handle, 1) != LIBUSB_SUCCESS) { + LOG_ERROR("Fail release interface 1"); + angie_quit(); + return ERROR_FAIL; + } } else { LOG_INFO("ANGIE device is already running ANGIE firmware"); } /* Get ANGIE USB IN/OUT endpoints and claim the interface */ ret = jtag_libusb_choose_interface(angie_handle->usb_device_handle, - &angie_handle->ep_in, &angie_handle->ep_out, -1, -1, -1, -1); + &angie_handle->ep_in, &angie_handle->ep_out, 0xFF, 0, 0, -1); if (ret != ERROR_OK) { + LOG_ERROR("Choose and claim interface failed"); angie_quit(); return ret; } diff --git a/src/jtag/drivers/angie/angie_firmware.bin b/src/jtag/drivers/angie/angie_firmware.bin index c793abb..bc85208 100644 Binary files a/src/jtag/drivers/angie/angie_firmware.bin and b/src/jtag/drivers/angie/angie_firmware.bin differ -- cgit v1.1