From fdcb50e0de9eedd99d7f1c501f7c0d8d9c32f876 Mon Sep 17 00:00:00 2001 From: Jens Hoffmann Date: Thu, 20 Feb 2014 13:28:04 +0100 Subject: [PATCH] Added support for ST nucleo devices. Nucleo boards using the same endpoint for IN and OUT (1). This patch fix it. --- 49-stlinkv2-1.rules | 12 ++++++++++++ src/stlink-common.h | 21 +++++++++++---------- src/stlink-usb.c | 9 +++++++-- 3 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 49-stlinkv2-1.rules diff --git a/49-stlinkv2-1.rules b/49-stlinkv2-1.rules new file mode 100644 index 0000000..a5a79b9 --- /dev/null +++ b/49-stlinkv2-1.rules @@ -0,0 +1,12 @@ +# stm32 nucleo boards, with onboard st/linkv2-1 +# ie, STM32F0, STM32F4. +# STM32VL has st/linkv1, which is quite different + +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", \ + MODE:="0666", \ + SYMLINK+="stlinkv2-1_%n" + +# If you share your linux system with other users, or just don't like the +# idea of write permission for everybody, you can replace MODE:="0666" with +# OWNER:="yourusername" to create the device owned by you, or with +# GROUP:="somegroupname" and mange access using standard unix groups. diff --git a/src/stlink-common.h b/src/stlink-common.h index ee16d5a..4005604 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -1,7 +1,7 @@ -/* +/* * File: stlink-common.h * Bulk import from stlink-hw.h - * + * * This should contain all the common top level stlink interfaces, regardless * of how the backend does the work.... */ @@ -24,6 +24,7 @@ extern "C" { #define USB_ST_VID 0x0483 #define USB_STLINK_PID 0x3744 #define USB_STLINK_32L_PID 0x3748 +#define USB_STLINK_NUCLEO_PID 0x374b // STLINK_DEBUG_RESETSYS, etc: #define STLINK_OK 0x80 @@ -67,7 +68,7 @@ extern "C" { #define STLINK_DEBUG_WRITEDEBUGREG 0x0f #define STLINK_DEBUG_ENTER_SWD 0xa3 #define STLINK_DEBUG_ENTER_JTAG 0x00 - + // TODO - possible poor names... #define STLINK_SWD_ENTER 0x30 #define STLINK_SWD_READCOREID 0x32 // TBD @@ -144,8 +145,8 @@ extern "C" { uint32_t sram_size; uint32_t bootrom_base, bootrom_size; } chip_params_t; - - + + // These maps are from a combination of the Programming Manuals, and // also the Reference manuals. (flash size reg is normally in ref man) static const chip_params_t devices[] = { @@ -324,7 +325,7 @@ static const chip_params_t devices[] = { }, }; - + typedef struct { uint32_t r[16]; uint32_t s[32]; @@ -341,7 +342,7 @@ static const chip_params_t devices[] = { } reg; typedef uint32_t stm32_addr_t; - + typedef struct _cortex_m3_cpuid_ { uint16_t implementer_id; uint16_t variant; @@ -431,7 +432,7 @@ static const chip_params_t devices[] = { #define STM32L_SRAM_SIZE (16 * 1024) stm32_addr_t sram_base; size_t sram_size; - + // bootloader stm32_addr_t sys_base; size_t sys_size; @@ -476,7 +477,7 @@ static const chip_params_t devices[] = { int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); int stlink_fwrite_sram(stlink_t *sl, const char* path, stm32_addr_t addr); int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, uint32_t length); - + // PUBLIC uint32_t stlink_chip_id(stlink_t *sl); void stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); @@ -502,7 +503,7 @@ static const chip_params_t devices[] = { #include "stlink-sg.h" -#include "stlink-usb.h" +#include "stlink-usb.h" diff --git a/src/stlink-usb.c b/src/stlink-usb.c index ec4053a..fe84183 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -782,7 +782,7 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { if (desc.idVendor!=USB_ST_VID) continue; if (devBus && devAddr) if ((libusb_get_bus_number(list[cnt])!=devBus) || (libusb_get_device_address(list[cnt])!=devAddr)) continue; - if (desc.idProduct == USB_STLINK_32L_PID) break; + if ( (desc.idProduct == USB_STLINK_32L_PID) || (desc.idProduct == USB_STLINK_NUCLEO_PID) ) break; if (desc.idProduct == USB_STLINK_PID) { slu->protocoll = 1; break; @@ -843,9 +843,14 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { WLOG("libusb_alloc_transfer failed\n"); goto on_libusb_error; } + // TODO - could use the scanning techniq from stm8 code here... slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; - slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; + if (desc.idProduct == USB_STLINK_NUCLEO_PID) { + slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT; + } else { + slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; + } slu->sg_transfer_idx = 0; // TODO - never used at the moment, always CMD_SIZE -- 2.30.2