From dee82a0d4fe2b649611525e5415f19186a051dfa Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 15 Feb 2013 17:39:27 +0100 Subject: Document changes between ST-Link V1 and V2 and implement needed changes --- src/platforms/stlink/Readme | 10 ++++++- src/platforms/stlink/platform.c | 62 +++++++++++++++++++++++++++++++++-------- src/platforms/stlink/platform.h | 4 +-- 3 files changed, 61 insertions(+), 15 deletions(-) (limited to 'src/platforms/stlink') diff --git a/src/platforms/stlink/Readme b/src/platforms/stlink/Readme index a677e55..b20a6db 100644 --- a/src/platforms/stlink/Readme +++ b/src/platforms/stlink/Readme @@ -1,3 +1,11 @@ Find a description how to modify a Discovery Board to use it's Stlink as black magic debug at -http://embdev.net/articles/STM_Discovery_as_Black_Magic_Probe \ No newline at end of file +http://embdev.net/articles/STM_Discovery_as_Black_Magic_Probe + +Differences between V1/V2 + + V1 V2 +ID Pins PC13/14 unconnected PC 13 pulled low +LED STLINK PA8, active High PA9, Dual Led +MCO Out NA PA8 +RESET(Target) T_JRST(PB1) NRST (PB0) diff --git a/src/platforms/stlink/platform.c b/src/platforms/stlink/platform.c index 40dcf8f..5eaf5fc 100644 --- a/src/platforms/stlink/platform.c +++ b/src/platforms/stlink/platform.c @@ -41,6 +41,34 @@ volatile uint32_t timeout_counter; jmp_buf fatal_error_jmpbuf; +uint16_t led_idle_run; +/* Pins PC[14:13] are used to detect hardware revision. Read + * 11 for STLink V1 e.g. on VL Discovery, tag as hwversion 0 + * 10 for STLink V2 e.g. on F4 Discovery, tag as hwversion 1 + */ +int platform_hwversion(void) +{ + static int hwversion = -1; + int i; + if (hwversion == -1) { + gpio_set_mode(GPIOC, GPIO_MODE_INPUT, + GPIO_CNF_INPUT_PULL_UPDOWN, + GPIO14 | GPIO13); + gpio_set(GPIOC, GPIO14 | GPIO13); + for (i = 0; i<10; i++) + hwversion = ~(gpio_get(GPIOC, GPIO14 | GPIO13) >> 13) & 3; + switch (hwversion) + { + case 0: + led_idle_run = GPIO8; + break; + default: + led_idle_run = GPIO9; + } + } + return hwversion; +} + int platform_init(void) { rcc_clock_setup_in_hse_8mhz_out_72mhz(); @@ -49,8 +77,19 @@ int platform_init(void) rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USBEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN); + /* On Rev 1 unconditionally activate MCO on PORTA8 with HSE + * platform_hwversion() also needed to initialize led_idle_run! + */ + if (platform_hwversion() == 1) + { + RCC_CFGR &= ~( 0xf<< 24); + RCC_CFGR |= (RCC_CFGR_MCO_HSECLK << 24); + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO8); + } /* Setup GPIO ports */ gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, TMS_PIN); @@ -60,13 +99,7 @@ int platform_init(void) GPIO_CNF_OUTPUT_PUSHPULL, TDI_PIN); gpio_set_mode(LED_PORT, GPIO_MODE_OUTPUT_2_MHZ, - GPIO_CNF_OUTPUT_PUSHPULL, LED_IDLE_RUN); - - /* unconditionally activate MCO on PORTA8 with HSE*/ - RCC_CFGR &= ~( 0xf<< 24); - RCC_CFGR |= (RCC_CFGR_MCO_HSECLK << 24); - gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, - GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO8); + GPIO_CNF_OUTPUT_PUSHPULL, led_idle_run); /* Setup heartbeat timer */ systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8); @@ -96,7 +129,7 @@ void platform_delay(uint32_t delay) void sys_tick_handler(void) { if(running_status) - gpio_toggle(LED_PORT, LED_IDLE_RUN); + gpio_toggle(LED_PORT, led_idle_run); if(timeout_counter) timeout_counter--; @@ -129,9 +162,14 @@ void disconnect_usb(void) void assert_boot_pin(void) { - rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); - gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, - GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); - gpio_set(GPIOC, GPIO13); + uint32_t crl = GPIOA_CRL; + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); + /* Enable Pull on GPIOA1. We don't rely on the external pin + * really pulled, but only on the value of the CNF register + * changed from the reset value + */ + crl &= 0xffffff0f; + crl |= 0x80; + GPIOA_CRL = crl; } void setup_vbus_irq(void){}; diff --git a/src/platforms/stlink/platform.h b/src/platforms/stlink/platform.h index 9b765fb..d22a4e2 100644 --- a/src/platforms/stlink/platform.h +++ b/src/platforms/stlink/platform.h @@ -81,7 +81,6 @@ extern usbd_device *usbdev; /* Use PC14 for a "dummy" uart led. So we can observere at least with scope*/ #define LED_PORT_UART GPIOC #define LED_UART GPIO14 -#define LED_IDLE_RUN GPIO9 #define TMS_SET_MODE() \ gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_50_MHZ, \ @@ -134,8 +133,9 @@ extern const char *morse_msg; gpio_clear((port), (pin)); \ } while(0) +extern uint16_t led_idle_run; #define SET_RUN_STATE(state) {running_status = (state);} -#define SET_IDLE_STATE(state) {gpio_set_val(LED_PORT, LED_IDLE_RUN, state);} +#define SET_IDLE_STATE(state) {gpio_set_val(LED_PORT, led_idle_run, state);} #define PLATFORM_SET_FATAL_ERROR_RECOVERY() {setjmp(fatal_error_jmpbuf);} #define PLATFORM_FATAL_ERROR(error) { \ -- cgit v1.2.3