From 9bc72d4519e63fb1cf657a6c93008eaa8989fd01 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sat, 22 Oct 2011 02:11:04 +0000 Subject: [PATCH] Merge upstream texane/master --- .gitignore | 1 + AUTHORS | 2 + Makefile | 41 +- TODO | 15 +- doc/tutorial/tutorial.pdf | Bin 106136 -> 110077 bytes doc/tutorial/tutorial.tex | 65 ++- example/blink/Makefile | 11 +- example/blink/main.c | 34 +- example/blink_flash/Makefile | 36 ++ example/blink_flash/main.c | 82 ++++ example/blink_flash/startup_stm32l1xx_md.s | 366 ++++++++++++++ example/blink_flash/stm32_flash.ld | 173 +++++++ example/blink_flash/system_stm32l1xx.c | 367 ++++++++++++++ flash/Makefile | 21 +- flash/main.c | 131 ++++- gdbserver/Makefile | 19 +- gdbserver/gdb-server.c | 53 ++- src/stlink-common.h | 1 + src/stlink-sg.c | 6 +- src/stlink-usb.c | 526 +++++++++++---------- src/stlink-usb.h | 6 +- src/test_sg.c | 4 +- src/test_usb.c | 2 +- 23 files changed, 1626 insertions(+), 336 deletions(-) create mode 100644 example/blink_flash/Makefile create mode 100644 example/blink_flash/main.c create mode 100644 example/blink_flash/startup_stm32l1xx_md.s create mode 100644 example/blink_flash/stm32_flash.ld create mode 100644 example/blink_flash/system_stm32l1xx.c diff --git a/.gitignore b/.gitignore index 78d3fb5..44d2e4d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ libstlink.a test_usb test_sg +gdbserver/st-utils \ No newline at end of file diff --git a/AUTHORS b/AUTHORS index ca1df75..0abaac6 100644 --- a/AUTHORS +++ b/AUTHORS @@ -7,3 +7,5 @@ karlp@tweak.net.au h0rr0rrdrag@gmail.com mstempin@com1.fr bon@elektron.ikp.physik.tu-darmstadt.de +nelsonjm@macpod.neta +ned@bike-nomad.com \ No newline at end of file diff --git a/Makefile b/Makefile index 4c3b44b..c5bb1d9 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,36 @@ - +# make ... for both libusb and libsg +# +# make CONFIG_USE_LIBSG=0 ... +# for just libusb +# VPATH=src -SOURCES_LIB=stlink-common.c stlink-usb.c stlink-sg.c +SOURCES_LIB=stlink-common.c stlink-usb.c OBJS_LIB=$(SOURCES_LIB:.c=.o) +TEST_PROGRAMS=test_usb +LDFLAGS=-lusb-1.0 -L. -lstlink + +ifeq ($(CONFIG_USE_LIBSG),) +CONFIG_USE_LIBSG=1 +endif + +ifneq ($(CONFIG_USE_LIBSG),0) +SOURCES_LIB+=stlink-sg.c +CFLAGS+=-DCONFIG_USE_LIBSG=1 +LDFLAGS+=-lsgutils2 +TEST_PROGRAMS+=test_sg +endif CFLAGS+=-g -CFLAGS+=-DCONFIG_USE_LIBUSB -CFLAGS+=-DCONFIG_USE_LIBSG -CFLAGS+=-DDEBUG +CFLAGS+=-DCONFIG_USE_LIBUSB=1 +CFLAGS+=-DDEBUG=1 CFLAGS+=-std=gnu99 CFLAGS+=-Wall -Wextra -LDFLAGS=-lstlink -lusb-1.0 -lsgutils2 -L. LIBRARY=libstlink.a -all: $(LIBRARY) test_usb test_sg +all: $(LIBRARY) flash gdbserver $(TEST_PROGRAMS) $(LIBRARY): $(OBJS_LIB) @echo "objs are $(OBJS_LIB)" @@ -42,5 +57,15 @@ clean: rm -rf $(LIBRARY) rm -rf test_usb* rm -rf test_sg* + +distclean: clean + $(MAKE) -C flash clean + $(MAKE) -C gdbserver clean -.PHONY: clean all +flash: + $(MAKE) -C flash CONFIG_USE_LIBSG="$(CONFIG_USE_LIBSG)" + +gdbserver: + $(MAKE) -C gdbserver + +.PHONY: clean all flash gdbserver diff --git a/TODO b/TODO index 4d1929c..e3795fc 100644 --- a/TODO +++ b/TODO @@ -1,10 +1,17 @@ -. flash writing is not working from GDB -add a standalone application, flash/ +. flash tool + . test support for reading + . writing is not working. refer to the specs, may have changed for stm32l + . then test with blink_flash example + . then update the documentation -. add a startup.S based example +. documentation + . make README points to doc/tutorial . remove libsg dependency using: https://github.com/afaerber/stlink/tree/master/libstlink . compile and test a realtime kernel, for instance: -http://www.chibios.org/dokuwiki/doku.php?id=start +http://www.chibios.org/dokuwiki/doku.php?id=chibios:articles:stm32l_discovery +svn checkout https://chibios.svn.sourceforge.net/svnroot/chibios/trunk ; +cd chibios/trunk/demos/ARMCM3-STM32L152-DISCOVERY ; +make ; diff --git a/doc/tutorial/tutorial.pdf b/doc/tutorial/tutorial.pdf index b84d061f57921ebc02df6a11261675a97c3d31fa..9202ed4dc33c1bcafdcf4db30807103a22c846c8 100644 GIT binary patch delta 65756 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 delta 62059 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 diff --git a/doc/tutorial/tutorial.tex b/doc/tutorial/tutorial.tex index cef3632..d1ba4fd 100644 --- a/doc/tutorial/tutorial.tex +++ b/doc/tutorial/tutorial.tex @@ -56,30 +56,37 @@ point of view, those versions differ only in the transport layer used to communi (v1 uses SCSI passthru commands, while v2 uses raw USB). \paragraph{} -Before continuing, the following dependencies are required: +Before continuing, the following dependencies must be met: \begin{itemize} \item libusb-1.0 -\item libsg2 +\item libsgutils2 (optionnal) \end{itemize} +\paragraph{} +STLINK should run on any system meeting the above constraints. + \paragraph{} The STLINK software source code is retrieved using:\\ \begin{small} \begin{lstlisting}[frame=tb] -git clone https://github.com/texane/stlink stlink.git +$> git clone https://github.com/texane/stlink stlink.git \end{lstlisting} \end{small} \paragraph{} -The GDB server is called st-util and is built using:\\ +Everything can be built from the top directory:\\ \begin{small} \begin{lstlisting}[frame=tb] -$> cd stlink.git; -$> make ; -$> cd gdbserver ; -$> make ; +$> cd stlink.git +$> make CONFIG_USE_LIBSG=0 \end{lstlisting} \end{small} +It includes: +\begin{itemize} +\item a communication library (stlink.git/libstlink.a), +\item a GDB server (stlink.git/gdbserver/st-util), +\item a flash manipulation tool (stlink.git/flash/flash). +\end{itemize} \newpage @@ -88,8 +95,9 @@ $> make ; A simple LED blinking example is provided in the example directory. It is built using:\\ \begin{small} \begin{lstlisting}[frame=tb] +# update the make option accordingly to your architecture cd stlink.git/example/blink ; -PATH=$TOOLCHAIN_PATH/bin:$PATH make ; +PATH=$TOOLCHAIN_PATH/bin:$PATH make CONFIG_STM32L_DISCOVERY=1; \end{lstlisting} \end{small} @@ -102,7 +110,8 @@ are using, you must run one of the 2 commands:\\ $> sudo ./st-util /dev/sg2 # STM32L discovery kit -$> sudo ./st-util +# 2 dummy command line arguments needed, will be fixed soon +$> sudo ./st-util fu bar \end{lstlisting} \end{small} @@ -144,6 +153,31 @@ $> continue The board BLUE and GREEN leds should be blinking (those leds are near the user and reset buttons). +\newpage +\section{Reading and writing to flash} +\paragraph{} +Flash memory reading and writing is done by a separate tool. A binary running in flash is assumed to +be linked against address 0x8000000. The flash tool is then used as shown below:\\ +\begin{small} +\begin{lstlisting}[frame=tb] +# change to the flash tool directory +$> cd stlink.git/flash ; + +# stlinkv1 command to read 4096 from flash into out.bin +$> ./flash read /dev/sg2 out.bin 0x8000000 4096 + +# stlinkv2 command +$> ./flash read out.bin 0x8000000 4096 + +# stlinkv1 command to write the file in.bin into flash +$> ./flash write /dev/sg2 in.bin 0x8000000 + +# stlinkv2 command +$> ./flash write in.bin 0x8000000 +\end{lstlisting} +\end{small} + + \newpage \section{Notes} @@ -187,6 +221,17 @@ $> make \end{lstlisting} \end{small} +\subsection{STM32VL support} +\paragraph{} +It seems support for STM32VL is quite broken. If it does not work, try build STLINK using libsg: +\begin{small} +\begin{lstlisting}[frame=tb] +$> cd stlink.git +$> make CONFIG_USE_LIBSG=1 +\end{lstlisting} +\end{small} + + \newpage \section{References} \begin{itemize} diff --git a/example/blink/Makefile b/example/blink/Makefile index 0f4f712..e5f7045 100644 --- a/example/blink/Makefile +++ b/example/blink/Makefile @@ -4,8 +4,15 @@ BIN_IMAGE=blink.bin CC=arm-none-eabi-gcc OBJCOPY=arm-none-eabi-objcopy -CFLAGS=-O2 -mlittle-endian -mthumb -g -CFLAGS+=-mcpu=cortex-m3 -ffreestanding -nostdlib -nostdinc +CFLAGS=-g -O2 -mlittle-endian -mthumb +ifeq ($(CONFIG_STM32L_DISCOVERY), 1) + CFLAGS+=-mcpu=cortex-m3 -DCONFIG_STM32L_DISCOVERY +else ifeq ($(CONFIG_STM32VL_DISCOVERY), 1) + CFLAGS+=-mcpu=cortex-m3 -DCONFIG_STM32VL_DISCOVERY=1 +else ifeq ($(CONFIG_STM32F4_DISCOVERY), 1) + CFLAGS+=-mcpu=cortex-m4 -DCONFIG_STM32F4_DISCOVERY=1 +endif + CFLAGS+=-ffreestanding -nostdlib -nostdinc # to run from SRAM CFLAGS+=-Wl,-Ttext,0x20000000 -Wl,-e,0x20000000 diff --git a/example/blink/main.c b/example/blink/main.c index 929e3b9..0889b81 100644 --- a/example/blink/main.c +++ b/example/blink/main.c @@ -5,10 +5,6 @@ typedef unsigned int uint32_t; /* hardware configuration */ -#define CONFIG_STM32L_DISCOVERY 1 -#define CONFIG_STM32VL_DISCOVERY 0 - - #if CONFIG_STM32VL_DISCOVERY # define GPIOC 0x40011000 /* port C */ @@ -58,6 +54,36 @@ static inline void switch_leds_off(void) *(volatile uint32_t*)GPIOB_ODR = 0; } +#elif CONFIG_STM32F4_DISCOVERY + +#define GPIOD 0x40020C00 /* port D */ +# define GPIOD_MODER (GPIOD + 0x00) /* port mode register */ +# define GPIOD_ODR (GPIOD + 0x14) /* port output data register */ + +# define LED_GREEN (1 << 12) /* port B, pin 12 */ +# define LED_ORANGE (1 << 13) /* port B, pin 13 */ +# define LED_RED (1 << 14) /* port B, pin 14 */ +# define LED_BLUE (1 << 15) /* port B, pin 15 */ + +static inline void setup_leds(void) +{ + *(volatile uint32_t*)GPIOD_MODER |= (1 << (12 * 2)) | (1 << (13 * 2)) | + (1 << (13 * 2)) | (1 << (14 * 2)) | (1 << (15 * 2)); +} + + +static inline void switch_leds_on(void) +{ + *(volatile uint32_t*)GPIOD_ODR = LED_GREEN | LED_ORANGE | LED_RED | LED_BLUE; +} + +static inline void switch_leds_off(void) +{ + *(volatile uint32_t*)GPIOD_ODR = 0; +} + +#else +#error "Architecture must be defined!" #endif /* otherwise, error */ diff --git a/example/blink_flash/Makefile b/example/blink_flash/Makefile new file mode 100644 index 0000000..7776471 --- /dev/null +++ b/example/blink_flash/Makefile @@ -0,0 +1,36 @@ +EXECUTABLE=blink.elf +BIN_IMAGE=blink.bin + +CC=arm-none-eabi-gcc +OBJCOPY=arm-none-eabi-objcopy + +CFLAGS=-O2 -mlittle-endian -mthumb + +CFLAGS=-g -O2 -mlittle-endian -mthumb +ifeq ($(CONFIG_STM32L_DISCOVERY), 1) + CFLAGS+=-mcpu=cortex-m3 -DCONFIG_STM32L_DISCOVERY +else ifeq ($(CONFIG_STM32VL_DISCOVERY), 1) + CFLAGS+=-mcpu=cortex-m3 -DCONFIG_STM32VL_DISCOVERY=1 +else ifeq ($(CONFIG_STM32F4_DISCOVERY), 1) + CFLAGS+=-mcpu=cortex-m4 -DCONFIG_STM32F4_DISCOVERY=1 +else +$(error "must specify CONFIG_ for board!") +endif + CFLAGS+=-ffreestanding -nostdlib -nostdinc + +# to run from FLASH +CFLAGS+=-Wl,-T,stm32_flash.ld + +all: $(BIN_IMAGE) + +$(BIN_IMAGE): $(EXECUTABLE) + $(OBJCOPY) -O binary $^ $@ + +$(EXECUTABLE): main.c startup_stm32l1xx_md.s + $(CC) $(CFLAGS) $^ -o $@ + +clean: + rm -rf $(EXECUTABLE) + rm -rf $(BIN_IMAGE) + +.PHONY: all clean diff --git a/example/blink_flash/main.c b/example/blink_flash/main.c new file mode 100644 index 0000000..e93fd72 --- /dev/null +++ b/example/blink_flash/main.c @@ -0,0 +1,82 @@ +/* missing type */ + +typedef unsigned int uint32_t; + + +/* hardware configuration */ + +#define CONFIG_STM32L_DISCOVERY 1 +#define CONFIG_STM32VL_DISCOVERY 0 + + +#if CONFIG_STM32VL_DISCOVERY + +# define GPIOC 0x40011000 /* port C */ +# define GPIOC_CRH (GPIOC + 0x04) /* port configuration register high */ +# define GPIOC_ODR (GPIOC + 0x0c) /* port output data register */ + +# define LED_BLUE (1 << 8) /* port C, pin 8 */ +# define LED_GREEN (1 << 9) /* port C, pin 9 */ + +static inline void setup_leds(void) +{ + *(volatile uint32_t*)GPIOC_CRH = 0x44444411; +} + +static inline void switch_leds_on(void) +{ + *(volatile uint32_t*)GPIOC_ODR = LED_BLUE | LED_GREEN; +} + +static inline void switch_leds_off(void) +{ + *(volatile uint32_t*)GPIOC_ODR = 0; +} + +#elif CONFIG_STM32L_DISCOVERY + +# define GPIOB 0x40020400 /* port B */ +# define GPIOB_MODER (GPIOB + 0x00) /* port mode register */ +# define GPIOB_ODR (GPIOB + 0x14) /* port output data register */ + +# define LED_BLUE (1 << 6) /* port B, pin 6 */ +# define LED_GREEN (1 << 7) /* port B, pin 7 */ + +static inline void setup_leds(void) +{ + /* configure port 6 and 7 as output */ + *(volatile uint32_t*)GPIOB_MODER |= (1 << (7 * 2)) | (1 << (6 * 2)); +} + +static inline void switch_leds_on(void) +{ + *(volatile uint32_t*)GPIOB_ODR = LED_BLUE | LED_GREEN; +} + +static inline void switch_leds_off(void) +{ + *(volatile uint32_t*)GPIOB_ODR = 0; +} + +#endif /* otherwise, error */ + + +#define delay() \ +do { \ + register unsigned int i; \ + for (i = 0; i < 1000000; ++i) \ + __asm__ __volatile__ ("nop\n\t":::"memory"); \ +} while (0) + +void main(void) +{ + setup_leds(); + + while (1) + { + switch_leds_on(); + delay(); + switch_leds_off(); + delay(); + } +} diff --git a/example/blink_flash/startup_stm32l1xx_md.s b/example/blink_flash/startup_stm32l1xx_md.s new file mode 100644 index 0000000..4ec8203 --- /dev/null +++ b/example/blink_flash/startup_stm32l1xx_md.s @@ -0,0 +1,366 @@ +/** + ****************************************************************************** + * @file startup_stm32l1xx_md.s + * @author MCD Application Team + * @version V1.0.0 + * @date 31-December-2010 + * @brief STM32L1xx Ultra Low Power Medium-density Devices vector table for + * RIDE7 toolchain. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M3 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ******************************************************************************* + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2010 STMicroelectronics

+ ******************************************************************************* + */ + + .syntax unified + .cpu cortex-m3 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss + +.equ BootRAM, 0xF108F85F +/** + * @brief This is the code that gets called when the processor first + * starts execution following a reset event. Only the absolutely + * necessary set is performed, after which the application + * supplied main() routine is called. + * @param None + * @retval : None +*/ + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + +/* Copy the data segment initializers from flash to SRAM */ + movs r1, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r3, =_sidata + ldr r3, [r3, r1] + str r3, [r0, r1] + adds r1, r1, #4 + +LoopCopyDataInit: + ldr r0, =_sdata + ldr r3, =_edata + adds r2, r0, r1 + cmp r2, r3 + bcc CopyDataInit + ldr r2, =_sbss + b LoopFillZerobss +/* Zero fill the bss segment. */ +FillZerobss: + movs r3, #0 + str r3, [r2], #4 + +LoopFillZerobss: + ldr r3, = _ebss + cmp r2, r3 + bcc FillZerobss +/* Call the clock system intitialization function.*/ +/* let main do the system initialization */ +/* bl SystemInit */ +/* Call the application's entry point.*/ + bl main + bx lr +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * + * @param None + * @retval None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/******************************************************************************* +* +* The minimal vector table for a Cortex M3. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +*******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + .word WWDG_IRQHandler + .word PVD_IRQHandler + .word TAMPER_STAMP_IRQHandler + .word RTC_WKUP_IRQHandler + .word FLASH_IRQHandler + .word RCC_IRQHandler + .word EXTI0_IRQHandler + .word EXTI1_IRQHandler + .word EXTI2_IRQHandler + .word EXTI3_IRQHandler + .word EXTI4_IRQHandler + .word DMA1_Channel1_IRQHandler + .word DMA1_Channel2_IRQHandler + .word DMA1_Channel3_IRQHandler + .word DMA1_Channel4_IRQHandler + .word DMA1_Channel5_IRQHandler + .word DMA1_Channel6_IRQHandler + .word DMA1_Channel7_IRQHandler + .word ADC1_IRQHandler + .word USB_HP_IRQHandler + .word USB_LP_IRQHandler + .word DAC_IRQHandler + .word COMP_IRQHandler + .word EXTI9_5_IRQHandler + .word LCD_IRQHandler + .word TIM9_IRQHandler + .word TIM10_IRQHandler + .word TIM11_IRQHandler + .word TIM2_IRQHandler + .word TIM3_IRQHandler + .word TIM4_IRQHandler + .word I2C1_EV_IRQHandler + .word I2C1_ER_IRQHandler + .word I2C2_EV_IRQHandler + .word I2C2_ER_IRQHandler + .word SPI1_IRQHandler + .word SPI2_IRQHandler + .word USART1_IRQHandler + .word USART2_IRQHandler + .word USART3_IRQHandler + .word EXTI15_10_IRQHandler + .word RTC_Alarm_IRQHandler + .word USB_FS_WKUP_IRQHandler + .word TIM6_IRQHandler + .word TIM7_IRQHandler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word BootRAM /* @0x108. This is for boot in RAM mode for + STM32L15x ULtra Low Power Medium-density devices. */ + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak PVD_IRQHandler + .thumb_set PVD_IRQHandler,Default_Handler + + .weak TAMPER_STAMP_IRQHandler + .thumb_set TAMPER_STAMP_IRQHandler,Default_Handler + + .weak RTC_WKUP_IRQHandler + .thumb_set RTC_WKUP_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak EXTI0_IRQHandler + .thumb_set EXTI0_IRQHandler,Default_Handler + + .weak EXTI1_IRQHandler + .thumb_set EXTI1_IRQHandler,Default_Handler + + .weak EXTI2_IRQHandler + .thumb_set EXTI2_IRQHandler,Default_Handler + + .weak EXTI3_IRQHandler + .thumb_set EXTI3_IRQHandler,Default_Handler + + .weak EXTI4_IRQHandler + .thumb_set EXTI4_IRQHandler,Default_Handler + + .weak DMA1_Channel1_IRQHandler + .thumb_set DMA1_Channel1_IRQHandler,Default_Handler + + .weak DMA1_Channel2_IRQHandler + .thumb_set DMA1_Channel2_IRQHandler,Default_Handler + + .weak DMA1_Channel3_IRQHandler + .thumb_set DMA1_Channel3_IRQHandler,Default_Handler + + .weak DMA1_Channel4_IRQHandler + .thumb_set DMA1_Channel4_IRQHandler,Default_Handler + + .weak DMA1_Channel5_IRQHandler + .thumb_set DMA1_Channel5_IRQHandler,Default_Handler + + .weak DMA1_Channel6_IRQHandler + .thumb_set DMA1_Channel6_IRQHandler,Default_Handler + + .weak DMA1_Channel7_IRQHandler + .thumb_set DMA1_Channel7_IRQHandler,Default_Handler + + .weak ADC1_IRQHandler + .thumb_set ADC1_IRQHandler,Default_Handler + + .weak USB_HP_IRQHandler + .thumb_set USB_HP_IRQHandler,Default_Handler + + .weak USB_LP_IRQHandler + .thumb_set USB_LP_IRQHandler,Default_Handler + + .weak DAC_IRQHandler + .thumb_set DAC_IRQHandler,Default_Handler + + .weak COMP_IRQHandler + .thumb_set COMP_IRQHandler,Default_Handler + + .weak EXTI9_5_IRQHandler + .thumb_set EXTI9_5_IRQHandler,Default_Handler + + .weak LCD_IRQHandler + .thumb_set LCD_IRQHandler,Default_Handler + + .weak TIM9_IRQHandler + .thumb_set TIM9_IRQHandler,Default_Handler + + .weak TIM10_IRQHandler + .thumb_set TIM10_IRQHandler,Default_Handler + + .weak TIM11_IRQHandler + .thumb_set TIM11_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak TIM3_IRQHandler + .thumb_set TIM3_IRQHandler,Default_Handler + + .weak TIM4_IRQHandler + .thumb_set TIM4_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C2_EV_IRQHandler + .thumb_set I2C2_EV_IRQHandler,Default_Handler + + .weak I2C2_ER_IRQHandler + .thumb_set I2C2_ER_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak USART2_IRQHandler + .thumb_set USART2_IRQHandler,Default_Handler + + .weak USART3_IRQHandler + .thumb_set USART3_IRQHandler,Default_Handler + + .weak EXTI15_10_IRQHandler + .thumb_set EXTI15_10_IRQHandler,Default_Handler + + .weak RTC_Alarm_IRQHandler + .thumb_set RTC_Alarm_IRQHandler,Default_Handler + + .weak USB_FS_WKUP_IRQHandler + .thumb_set USB_FS_WKUP_IRQHandler,Default_Handler + + .weak TIM6_IRQHandler + .thumb_set TIM6_IRQHandler,Default_Handler + + .weak TIM7_IRQHandler + .thumb_set TIM7_IRQHandler,Default_Handler + +/******************** (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE***/ + diff --git a/example/blink_flash/stm32_flash.ld b/example/blink_flash/stm32_flash.ld new file mode 100644 index 0000000..146b16e --- /dev/null +++ b/example/blink_flash/stm32_flash.ld @@ -0,0 +1,173 @@ +/* +***************************************************************************** +** +** File : stm32_flash.ld +** +** Abstract : Linker script for STM32L152RB Device with +** 128KByte FLASH, 16KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Environment : Atollic TrueSTUDIO(R) +** +** Distribution: The file is distributed “as is,” without any warranty +** of any kind. +** +** (c)Copyright Atollic AB. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Atollic AB permit registered Atollic TrueSTUDIO(R) users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the Atollic TrueSTUDIO(R) toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20004000; /* end of 16K RAM */ + +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0; /* required amount of heap */ +_Min_Stack_Size = 0x80; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K + MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K + RW_EEPROM (rw) : ORIGIN = 0x08080000, LENGTH = 32 +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array*)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = .; + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : AT ( _sidata ) + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(4); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(4); + } >RAM + + /* MEMORY_bank1 section, code must be located here explicitly */ + /* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */ + .memory_b1_text : + { + *(.mb1text) /* .mb1text sections (code) */ + *(.mb1text*) /* .mb1text* sections (code) */ + *(.mb1rodata) /* read-only data (constants) */ + *(.mb1rodata*) + } >MEMORY_B1 + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } + + .DataFlash (NOLOAD): {*(.DataFlash)} >RW_EEPROM +} diff --git a/example/blink_flash/system_stm32l1xx.c b/example/blink_flash/system_stm32l1xx.c new file mode 100644 index 0000000..6deab32 --- /dev/null +++ b/example/blink_flash/system_stm32l1xx.c @@ -0,0 +1,367 @@ +/** + ****************************************************************************** + * @file system_stm32l1xx.c + * @author MCD Application Team + * @version V1.0.0 + * @date 2-June-2011 + * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File. + * This file contains the system clock configuration for STM32L1xx Ultra + * Low Medium-density devices, and is generated by the clock configuration + * tool "STM32L1xx_Clock_Configuration_V1.0.0.xls". + * + * 1. This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier + * and Divider factors, AHB/APBx prescalers and Flash settings), + * depending on the configuration made in the clock xls tool. + * This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32l1xx_md.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * 2. After each device reset the MSI (2.1 MHz Range) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32l1xx_md.s" file, to + * configure the system clock before to branch to main program. + * + * 3. If the system clock source selected by user fails to startup, the SystemInit() + * function will do nothing and MSI still used as system clock source. User can + * add some code to deal with this issue inside the SetSysClock() function. + * + * 4. The default value of HSE crystal is set to 8MHz, refer to "HSE_VALUE" define + * in "stm32l1xx.h" file. When HSE is used as system clock source, directly or + * through PLL, and you are using different crystal you have to adapt the HSE + * value to your own configuration. + * + * 5. This file configures the system clock as follows: + *============================================================================= + * System Clock Configuration + *============================================================================= + * System clock source | HSI + *----------------------------------------------------------------------------- + * SYSCLK | 16000000 Hz + *----------------------------------------------------------------------------- + * HCLK | 16000000 Hz + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 1 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 1 + *----------------------------------------------------------------------------- + * HSE Frequency | 8000000 Hz + *----------------------------------------------------------------------------- + * PLL DIV | Not Used + *----------------------------------------------------------------------------- + * PLL MUL | Not Used + *----------------------------------------------------------------------------- + * VDD | 3.3 V + *----------------------------------------------------------------------------- + * Vcore | 1.8 V (Range 1) + *----------------------------------------------------------------------------- + * Flash Latency | 0 WS + *----------------------------------------------------------------------------- + * Require 48MHz for USB clock | Disabled + *----------------------------------------------------------------------------- + *============================================================================= + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2010 STMicroelectronics

+ ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32l1xx_system + * @{ + */ + +/** @addtogroup STM32L1xx_System_Private_Includes + * @{ + */ + +#include "stm32l1xx.h" + +/** + * @} + */ + +/** @addtogroup STM32L1xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L1xx_System_Private_Defines + * @{ + */ +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +/** + * @} + */ + +/** @addtogroup STM32L1xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L1xx_System_Private_Variables + * @{ + */ +uint32_t SystemCoreClock = 16000000; +__I uint8_t PLLMulTable[9] = {3, 4, 6, 8, 12, 16, 24, 32, 48}; +__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + +/** + * @} + */ + +/** @addtogroup STM32L1xx_System_Private_FunctionPrototypes + * @{ + */ + +static void SetSysClock(void); + +/** + * @} + */ + +/** @addtogroup STM32L1xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * Initialize the Embedded Flash Interface, the PLL and update the + * SystemCoreClock variable. + * @param None + * @retval None + */ +void SystemInit (void) +{ + /*!< Set MSION bit */ + RCC->CR |= (uint32_t)0x00000100; + + /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ + RCC->CFGR &= (uint32_t)0x88FFC00C; + + /*!< Reset HSION, HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xEEFEFFFE; + + /*!< Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + + /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */ + RCC->CFGR &= (uint32_t)0xFF02FFFF; + + /*!< Disable all interrupts */ + RCC->CIR = 0x00000000; + + /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */ + SetSysClock(); + +#ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */ +#else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */ +#endif +} + +/** + * @brief Update SystemCoreClock according to Clock Register Values + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI + * value as defined by the MSI range. + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in stm32l1xx.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSE_VALUE is a constant defined in stm32l1xx.h file (default value + * 8 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * @param None + * @retval None + */ +void SystemCoreClockUpdate (void) +{ + uint32_t tmp = 0, pllmul = 0, plldiv = 0, pllsource = 0, msirange = 0; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* MSI used as system clock */ + msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13; + SystemCoreClock = (32768 * (1 << (msirange + 1))); + break; + case 0x04: /* HSI used as system clock */ + SystemCoreClock = HSI_VALUE; + break; + case 0x08: /* HSE used as system clock */ + SystemCoreClock = HSE_VALUE; + break; + case 0x0C: /* PLL used as system clock */ + /* Get PLL clock source and multiplication factor ----------------------*/ + pllmul = RCC->CFGR & RCC_CFGR_PLLMUL; + plldiv = RCC->CFGR & RCC_CFGR_PLLDIV; + pllmul = PLLMulTable[(pllmul >> 18)]; + plldiv = (plldiv >> 22) + 1; + + pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; + + if (pllsource == 0x00) + { + /* HSI oscillator clock selected as PLL clock entry */ + SystemCoreClock = (((HSI_VALUE) * pllmul) / plldiv); + } + else + { + /* HSE selected as PLL clock entry */ + SystemCoreClock = (((HSE_VALUE) * pllmul) / plldiv); + } + break; + default: /* MSI used as system clock */ + msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13; + SystemCoreClock = (32768 * (1 << (msirange + 1))); + break; + } + /* Compute HCLK clock frequency --------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; +} + +/** + * @brief Configures the System clock frequency, AHB/APBx prescalers and Flash + * settings. + * @note This function should be called only once the RCC clock configuration + * is reset to the default reset state (done in SystemInit() function). + * @param None + * @retval None + */ +static void SetSysClock(void) +{ + __IO uint32_t StartUpCounter = 0, HSIStatus = 0; + + /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ + /* Enable HSI */ + RCC->CR |= ((uint32_t)RCC_CR_HSION); + + /* Wait till HSI is ready and if Time out is reached exit */ + do + { + HSIStatus = RCC->CR & RCC_CR_HSIRDY; + } while((HSIStatus == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT)); + + if ((RCC->CR & RCC_CR_HSIRDY) != RESET) + { + HSIStatus = (uint32_t)0x01; + } + else + { + HSIStatus = (uint32_t)0x00; + } + + if (HSIStatus == (uint32_t)0x01) + { + /* Flash 0 wait state */ + FLASH->ACR &= ~FLASH_ACR_LATENCY; + + /* Disable Prefetch Buffer */ + FLASH->ACR &= ~FLASH_ACR_PRFTEN; + + /* Disable 64-bit access */ + FLASH->ACR &= ~FLASH_ACR_ACC64; + + + /* Power enable */ + RCC->APB1ENR |= RCC_APB1ENR_PWREN; + + /* Select the Voltage Range 1 (1.8 V) */ + PWR->CR = PWR_CR_VOS_0; + + + /* Wait Until the Voltage Regulator is ready */ + while((PWR->CSR & PWR_CSR_VOSF) != RESET) + { + } + + /* HCLK = SYSCLK /1*/ + RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; + /* PCLK2 = HCLK /1*/ + RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; + + /* PCLK1 = HCLK /1*/ + RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; + + /* Select HSI as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSI; + + /* Wait till HSI is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_HSI) + { + } + } + else + { + /* If HSI fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/flash/Makefile b/flash/Makefile index fe0dff7..8a30b41 100644 --- a/flash/Makefile +++ b/flash/Makefile @@ -1,12 +1,27 @@ +# make ... for both libusb and libsg +# +# make CONFIG_USE_LIBSG=0 ... +# for just libusb +# +CC=gcc + CFLAGS+=-g -CFLAGS+=-DCONFIG_USE_LIBUSB -CFLAGS+=-DCONFIG_USE_LIBSG +CFLAGS+=-DCONFIG_USE_LIBUSB=1 CFLAGS+=-DDEBUG CFLAGS+=-std=gnu99 CFLAGS+=-Wall -Wextra CFLAGS+=-I../src -LDFLAGS=-L.. -lstlink -lusb-1.0 -lsgutils2 +LDFLAGS=-lusb-1.0 -L.. -lstlink + +ifeq ($(CONFIG_USE_LIBSG),) +CONFIG_USE_LIBSG=1 +endif + +ifneq ($(CONFIG_USE_LIBSG),0) +CFLAGS+=-DCONFIG_USE_LIBSG=1 +LDFLAGS+=-lsgutils2 +endif SRCS=main.c OBJS=$(SRCS:.c=.o) diff --git a/flash/main.c b/flash/main.c index c8b15e0..e474174 100644 --- a/flash/main.c +++ b/flash/main.c @@ -3,47 +3,134 @@ #include #include +#include +#include #include "stlink-common.h" -int main(int ac, char** av) +struct opts { - /* stlinkv1 command line: ./flash /dev/sgX path addr */ - /* stlinkv2 command line: ./flash path addr */ - - stlink_t* sl = NULL; + unsigned int do_read; + const char* devname; + const char* filename; stm32_addr_t addr; - const char* path; - int err; + size_t size; +}; + +static void usage(void) +{ + puts("stlinkv1 command line: ./flash {read|write} /dev/sgX path addr "); + puts("stlinkv2 command line: ./flash {read|write} path addr "); +} + +static int get_opts(struct opts* o, int ac, char** av) +{ + /* stlinkv1 command line: ./flash {read|write} /dev/sgX path addr */ + /* stlinkv2 command line: ./flash {read|write} path addr */ + + unsigned int i = 0; + + if (ac < 3) return -1; - if (ac == 4) /* stlinkv1 */ + /* stlinkv2 */ + o->devname = NULL; + + if (strcmp(av[0], "read") == 0) { - static const int scsi_verbose = 2; - sl = stlink_quirk_open(av[1], scsi_verbose); - path = av[2]; - addr = strtoul(av[3], NULL, 16); + o->do_read = 1; + + /* stlinkv1 mode */ + if (ac == 5) + { + o->devname = av[1]; + i = 1; + } + + o->size = strtoul(av[i + 3], NULL, 10); } - else if (ac == 3) /* stlinkv2 */ + else if (strcmp(av[0], "write") == 0) { - sl = stlink_open_usb(NULL, 10); - path = av[1]; - addr = strtoul(av[2], NULL, 16); + o->do_read = 0; + + /* stlinkv1 mode */ + if (ac == 4) + { + o->devname = av[1]; + i = 1; + } } - else /* invalid */ + else + { + return -1; + } + + o->filename = av[i + 1]; + o->addr = strtoul(av[i + 2], NULL, 16); + + return 0; +} + + +int main(int ac, char** av) +{ + stlink_t* sl = NULL; + struct opts o; + int err = -1; + + if (get_opts(&o, ac - 1, av + 1) == -1) { printf("invalid command line\n"); + usage(); goto on_error; } - if (sl == NULL) goto on_error; - - err = stlink_fwrite_flash(sl, path, addr); - if (err == -1) + if (o.devname != NULL) /* stlinkv1 */ { - printf("stlink_fwrite_flash() == -1\n"); +#if CONFIG_USE_LIBSG + static const int scsi_verbose = 2; + sl = stlink_quirk_open(o.devname, scsi_verbose); + if (sl == NULL) goto on_error; +#else + printf("not compiled for use with STLink/V1"); goto on_error; +#endif + } + else /* stlinkv2 */ + { + sl = stlink_open_usb(10); + if (sl == NULL) goto on_error; } + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) + stlink_exit_dfu_mode(sl); + + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) + stlink_enter_swd_mode(sl); + + stlink_reset(sl); + + if (o.do_read == 0) /* write */ + { + err = stlink_fwrite_flash(sl, o.filename, o.addr); + if (err == -1) + { + printf("stlink_fwrite_flash() == -1\n"); + goto on_error; + } + } + else /* read */ + { + err = stlink_fread(sl, o.filename, o.addr, o.size); + if (err == -1) + { + printf("stlink_fread() == -1\n"); + goto on_error; + } + } + + /* success */ + err = 0; + on_error: if (sl != NULL) stlink_close(sl); diff --git a/gdbserver/Makefile b/gdbserver/Makefile index e9d2774..a8d1b90 100644 --- a/gdbserver/Makefile +++ b/gdbserver/Makefile @@ -1,13 +1,24 @@ +# make ... for both libusb and libsg +# +# make CONFIG_USE_LIBSG=0 ... +# for just libusb +# PRG := st-util OBJS = gdb-remote.o gdb-server.o CFLAGS+=-g -Wall -Werror -std=gnu99 -I../src -CFLAGS+=-DCONFIG_USE_LIBUSB -CFLAGS+=-DCONFIG_USE_LIBSG -LIBS := -lstlink -lusb-1.0 -lsgutils2 -LDFLAGS+=$(LIBS) -L.. +CFLAGS+=-DCONFIG_USE_LIBUSB=1 +LDFLAGS=-lusb-1.0 -L.. -lstlink +ifeq ($(CONFIG_USE_LIBSG),) +CONFIG_USE_LIBSG=1 +endif + +ifneq ($(CONFIG_USE_LIBSG),0) +CFLAGS+=-DCONFIG_USE_LIBSG=1 +LDFLAGS+=-lsgutils2 +endif all: $(PRG) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 72f433f..67f0be0 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -24,6 +25,12 @@ #define FLASH_PAGE_MASK (~((1 << 10) - 1)) #define FLASH_SIZE (FLASH_PAGE * 128) +volatile int do_exit = 0; +void ctrl_c(int sig) +{ + do_exit = 1; +} + static const char hex[] = "0123456789abcdef"; static const char* current_memory_map = NULL; @@ -32,6 +39,11 @@ static const char* current_memory_map = NULL; * Chip IDs are explained in the appropriate programming manual for the * DBGMCU_IDCODE register (0xE0042000) */ + +#define CORE_M3_R1 0x1BA00477 +#define CORE_M3_R2 0x4BA00477 +#define CORE_M4_R0 0x2BA01477 + struct chip_params { uint32_t chip_id; char* description; @@ -43,11 +55,11 @@ struct chip_params { { 0x410, "F1 Medium-density device", 0x1ffff7e0, 0x20000, 0x400, 0x5000, 0x1ffff000, 0x800 }, // table 2, pm0063 { 0x411, "F2 device", 0, /* No flash size register found in the docs*/ - 0x100000, 0x20000, 0x20000, 0x1ff00000, 0x7800 }, // table 1, pm0059 + 0x100000, 0x20000, 0x20000, 0x1fff0000, 0x7800 }, // table 1, pm0059 { 0x412, "F1 Low-density device", 0x1ffff7e0, 0x8000, 0x400, 0x2800, 0x1ffff000, 0x800 }, // table 1, pm0063 { 0x413, "F4 device", 0x1FFF7A10, - 0x100000, 0x20000, 0x20000, 0x1ff00000, 0x7800 }, // table 1, pm0081 + 0x100000, 0x20000, 0x30000, 0x1fff0000, 0x7800 }, // table 1, pm0081 { 0x414, "F1 High-density device", 0x1ffff7e0, 0x80000, 0x800, 0x10000, 0x1ffff000, 0x800 }, // table 3 pm0063 // This ignores the EEPROM! (and uses the page erase size, @@ -79,15 +91,10 @@ int main(int argc, char** argv) { switch(argc) { - default: { - fprintf(stderr, HelpStr, NULL); - return 1; - } - case 3 : { //sl = stlink_quirk_open(argv[2], 0); - // FIXME - hardcoded to usb.... - sl = stlink_open_usb(argv[2], 10); + // FIXME - hardcoded to usb.... + sl = stlink_open_usb(10); if(sl == NULL) return 1; break; } @@ -99,6 +106,7 @@ int main(int argc, char** argv) { } } +#if CONFIG_USE_LIBSG case 1 : { // Search ST-LINK (from /dev/sg0 to /dev/sg99) const int DevNumMax = 99; int ExistDevCount = 0; @@ -136,18 +144,32 @@ int main(int argc, char** argv) { } break; } +#endif + + default: { + fprintf(stderr, HelpStr, NULL); + return 1; + } } - if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { - stlink_exit_dfu_mode(sl); - } + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { + stlink_exit_dfu_mode(sl); + } if(stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } uint32_t chip_id = stlink_chip_id(sl); - printf("Chip ID is %08x.\n", chip_id); + uint32_t core_id = stlink_core_id(sl); + + /* Fix chip_id for F4 */ + if (((chip_id & 0xFFF) == 0x411) && (core_id == CORE_M4_R0)) { + printf("Fixing wrong chip_id for STM32F4 Rev A errata\n"); + chip_id = 0x413; + } + + printf("Chip ID is %08x, Core ID is %08x.\n", chip_id, core_id); const struct chip_params* params = NULL; @@ -182,6 +204,9 @@ int main(int argc, char** argv) { while(serve(sl, port) == 0); + /* Switch back to mass storage mode before closing. */ + stlink_run(sl); + stlink_exit_debug_mode(sl); stlink_close(sl); return 0; @@ -578,7 +603,9 @@ int serve(stlink_t *sl, int port) { printf("Listening at *:%d...\n", port); + (void) signal (SIGINT, ctrl_c); int client = accept(sock, NULL, NULL); + signal (SIGINT, SIG_DFL); if(client < 0) { perror("accept"); return 1; diff --git a/src/stlink-common.h b/src/stlink-common.h index cb6c6cc..9481609 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -175,6 +175,7 @@ extern "C" { /* sram settings */ #define STM32_SRAM_BASE 0x20000000 #define STM32_SRAM_SIZE (8 * 1024) +#define STM32L_SRAM_SIZE (16 * 1024) stm32_addr_t sram_base; size_t sram_size; diff --git a/src/stlink-sg.c b/src/stlink-sg.c index f8865e1..b8220de 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -80,12 +80,14 @@ #include #include +#include "stlink-common.h" + +#if CONFIG_USE_LIBSG // sgutils2 (apt-get install libsgutils2-dev) #include #include - -#include "stlink-common.h" #include "stlink-sg.h" +#endif // Suspends execution of the calling process for diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 2433d6c..ff9ef71 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -9,6 +8,8 @@ #include "stlink-common.h" #include "stlink-usb.h" +enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80}; + void _stlink_usb_close(stlink_t* sl) { struct stlink_libusb * const handle = sl->backend_data; // maybe we couldn't even get the usb device? @@ -19,8 +20,9 @@ void _stlink_usb_close(stlink_t* sl) { if (handle->rep_trans != NULL) libusb_free_transfer(handle->rep_trans); - if (handle->usb_handle != NULL) + if (handle->usb_handle != NULL) { libusb_close(handle->usb_handle); + } libusb_exit(handle->libusb_ctx); free(handle); @@ -88,10 +90,11 @@ int submit_wait(struct stlink_libusb *slu, struct libusb_transfer * trans) { return 0; } -ssize_t send_recv(struct stlink_libusb* handle, +ssize_t send_recv(struct stlink_libusb* handle, int terminate, unsigned char* txbuf, size_t txsize, unsigned char* rxbuf, size_t rxsize) { /* note: txbuf and rxbuf can point to the same area */ + int res = 0; libusb_fill_bulk_transfer(handle->req_trans, handle->usb_handle, handle->ep_req, @@ -100,122 +103,146 @@ ssize_t send_recv(struct stlink_libusb* handle, 0 ); - printf("submit_wait(req)\n"); - if (submit_wait(handle, handle->req_trans)) return -1; /* send_only */ - if (rxsize == 0) return 0; - - /* read the response */ - - libusb_fill_bulk_transfer(handle->rep_trans, handle->usb_handle, - handle->ep_rep, rxbuf, rxsize, NULL, NULL, 0); - - printf("submit_wait(rep)\n"); - - if (submit_wait(handle, handle->rep_trans)) return -1; + if (rxsize != 0) { + + /* read the response */ + + libusb_fill_bulk_transfer(handle->rep_trans, handle->usb_handle, + handle->ep_rep, rxbuf, rxsize, NULL, NULL, 0); + + if (submit_wait(handle, handle->rep_trans)) return -1; + res = handle->rep_trans->actual_length; + } + if ((handle->protocoll == 1) && terminate) { + /* Read the SG reply */ + unsigned char sg_buf[13]; + libusb_fill_bulk_transfer + (handle->rep_trans, handle->usb_handle, + handle->ep_rep, sg_buf, 13, NULL, NULL, 0); + res = submit_wait(handle, handle->rep_trans); + /* The STLink doesn't seem to evaluate the sequence number */ + handle->sg_transfer_idx++; + if (res ) return -1; + } return handle->rep_trans->actual_length; } static inline int send_only -(struct stlink_libusb* handle, unsigned char* txbuf, size_t txsize) { - return send_recv(handle, txbuf, txsize, NULL, 0); +(struct stlink_libusb* handle, int terminate, + unsigned char* txbuf, size_t txsize) { + return send_recv(handle, terminate, txbuf, txsize, NULL, 0); } -// KARL - fixme, common code! (or, one per backend) -// candidate for common code... - - -static int is_stlink_device(libusb_device * dev) { +/* Search for a STLINK device, either any or teh one with the given PID + * Return the protocoll version + */ +static int is_stlink_device(libusb_device * dev, uint16_t pid) { struct libusb_device_descriptor desc; + int version; if (libusb_get_device_descriptor(dev, &desc)) return 0; - printf("device: 0x%04x, 0x%04x\n", desc.idVendor, desc.idProduct); - if (desc.idVendor != USB_ST_VID) return 0; - if (desc.idProduct != USB_STLINK_32L_PID) + if ((desc.idProduct != USB_STLINK_32L_PID) && + (desc.idProduct != USB_STLINK_PID )) + return 0; + + if(pid && (pid != desc.idProduct)) return 0; + if (desc.idProduct == USB_STLINK_PID ) + version = 1; + else + version = 2; - return 1; + return version; +} + +static int fill_command +(stlink_t * sl, enum SCSI_Generic_Direction dir, uint32_t len) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const cmd = sl->c_buf; + int i = 0; + memset(cmd, 0, sizeof (sl->c_buf)); + if(slu->protocoll == 1) { + cmd[i++] = 'U'; + cmd[i++] = 'S'; + cmd[i++] = 'B'; + cmd[i++] = 'C'; + write_uint32(&cmd[i], slu->sg_transfer_idx); + write_uint32(&cmd[i + 4], len); + i += 8; + cmd[i++] = (dir == SG_DXFER_FROM_DEV)?0x80:0; + cmd[i++] = 0; /* Logical unit */ + cmd[i++] = 0xa; /* Command length */ + } + return i; } void _stlink_usb_version(stlink_t *sl) { struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; ssize_t size; + uint32_t rep_len = 6; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - memset(buf, 0, sizeof (sl->q_buf)); - buf[0] = STLINK_GET_VERSION; - buf[1] = 0x80; + cmd[i++] = STLINK_GET_VERSION; - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 6); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); return; } - -#if 1 /* DEBUG */ - { - ssize_t i; - for (i = 0; i < size; ++i) printf("%02x", buf[i]); - printf("\n"); - } -#endif /* DEBUG */ } void _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; - unsigned char *cmd_buf = sl->c_buf; - - memset(cmd_buf, 0, STLINK_CMD_SIZE); - cmd_buf[0] = STLINK_DEBUG_COMMAND; - cmd_buf[1] = STLINK_DEBUG_WRITEMEM_32BIT; - write_uint32(cmd_buf + 2, addr); - write_uint16(cmd_buf + 6, len); - send_only(slu, cmd_buf, STLINK_CMD_SIZE); - -#if Q_BUF_LEN < UINT16_MAX - assert(len < sizeof(sl->q_buf)); // makes a compiler warning? always true? -#endif - assert((len & 3) == 0); - send_only(slu, buf, len); + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + + int i = fill_command(sl, SG_DXFER_TO_DEV, len); + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_WRITEMEM_32BIT; + write_uint32(&cmd[i], addr); + write_uint16(&cmd[i + 4], len); + send_only(slu, 0, cmd, slu->cmd_len); + send_only(slu, 1, data, len); } void _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; - unsigned char *cmd_buf = sl->c_buf; - - memset(cmd_buf, 0, STLINK_CMD_SIZE); - cmd_buf[0] = STLINK_DEBUG_COMMAND; - cmd_buf[1] = STLINK_DEBUG_WRITEMEM_8BIT; - write_uint32(cmd_buf + 2, addr); - write_uint16(cmd_buf + 6, len); - send_only(slu, cmd_buf, STLINK_CMD_SIZE); - -#if Q_BUF_LEN < UINT16_MAX - assert(len < sizeof(sl->q_buf)); // makes a compiler warning? always true? -#endif - send_only(slu, buf, len); + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + + int i = fill_command(sl, SG_DXFER_TO_DEV, 0); + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_WRITEMEM_8BIT; + write_uint32(&cmd[i], addr); + write_uint16(&cmd[i + 4], len); + send_only(slu, 0, cmd, slu->cmd_len); + send_only(slu, 1, data, len); } int _stlink_usb_current_mode(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + unsigned char* const data = sl->q_buf; ssize_t size; - memset(buf, 0, sizeof (sl->q_buf)); - buf[0] = STLINK_GET_CURRENT_MODE; - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2); + int rep_len = 2; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + + cmd[i++] = STLINK_GET_CURRENT_MODE; + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); return -1; @@ -225,76 +252,71 @@ int _stlink_usb_current_mode(stlink_t * sl) { void _stlink_usb_core_id(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + unsigned char* const data = sl->q_buf; ssize_t size; + int rep_len = 4; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - memset(buf, 0, sizeof (sl->q_buf)); - buf[0] = STLINK_DEBUG_COMMAND; - buf[1] = STLINK_DEBUG_READCOREID; + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_READCOREID; - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 4); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); return; } - sl->core_id = read_uint32(buf, 0); + sl->core_id = read_uint32(data, 0); } void _stlink_usb_status(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; ssize_t size; + int rep_len = 2; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - memset(buf, 0, sizeof (sl->q_buf)); + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_GETSTATUS; - buf[0] = STLINK_DEBUG_COMMAND; - buf[1] = STLINK_DEBUG_GETSTATUS; - - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); return; } - - /* todo: stlink_core_stat */ - - // FIXME - decode into sl->core_stat -#if 1 /* DEBUG */ - printf("status == 0x%x\n", buf[0]); -#endif /* DEBUG */ - } void _stlink_usb_force_debug(stlink_t *sl) { struct stlink_libusb *slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; ssize_t size; + int rep_len = 2; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - memset(buf, 0, sizeof (sl->q_buf)); - - buf[0] = STLINK_DEBUG_COMMAND; - buf[1] = STLINK_DEBUG_FORCEDEBUG; - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2); + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_FORCEDEBUG; + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); return; } } - void _stlink_usb_enter_swd_mode(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; + unsigned char* const cmd = sl->c_buf; ssize_t size; + const int rep_len = 0; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - memset(buf, 0, sizeof (sl->q_buf)); + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_ENTER; + cmd[i++] = STLINK_DEBUG_ENTER_SWD; - buf[0] = STLINK_DEBUG_COMMAND; - buf[1] = STLINK_SWD_ENTER; - buf[2] = STLINK_DEBUG_ENTER_SWD; - - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2); + size = send_only(slu, 1, cmd, slu->cmd_len); if (size == -1) { printf("[!] send_recv\n"); return; @@ -303,14 +325,14 @@ void _stlink_usb_enter_swd_mode(stlink_t * sl) { void _stlink_usb_exit_dfu_mode(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; + unsigned char* const cmd = sl->c_buf; ssize_t size; + int i = fill_command(sl, SG_DXFER_FROM_DEV, 0); - memset(buf, 0, sizeof (sl->q_buf)); - buf[0] = STLINK_DFU_COMMAND; - buf[1] = STLINK_DFU_EXIT; + cmd[i++] = STLINK_DFU_COMMAND; + cmd[i++] = STLINK_DFU_EXIT; - size = send_only(slu, buf, 16); + size = send_only(slu, 1, cmd, slu->cmd_len); if (size == -1) { printf("[!] send_recv\n"); return; @@ -323,14 +345,16 @@ void _stlink_usb_exit_dfu_mode(stlink_t* sl) { */ void _stlink_usb_reset(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; ssize_t size; + int rep_len = 2; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - memset(buf, 0, sizeof (sl->q_buf)); - buf[0] = STLINK_DEBUG_COMMAND; - buf[1] = STLINK_DEBUG_RESETSYS; + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_RESETSYS; - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); return; @@ -340,14 +364,16 @@ void _stlink_usb_reset(stlink_t * sl) { void _stlink_usb_step(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; ssize_t size; + int rep_len = 2; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - memset(buf, 0, sizeof (sl->q_buf)); - buf[0] = STLINK_DEBUG_COMMAND; - buf[1] = STLINK_DEBUG_STEPCORE; + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_STEPCORE; - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); return; @@ -360,31 +386,32 @@ void _stlink_usb_step(stlink_t* sl) { */ void _stlink_usb_run(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; ssize_t size; + int rep_len = 2; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - memset(buf, 0, sizeof (sl->q_buf)); - buf[0] = STLINK_DEBUG_COMMAND; - buf[1] = STLINK_DEBUG_RUNCORE; + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_RUNCORE; - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); return; } - } void _stlink_usb_exit_debug_mode(stlink_t *sl) { struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; + unsigned char* const cmd = sl->c_buf; ssize_t size; + int i = fill_command(sl, SG_DXFER_FROM_DEV, 0); - memset(buf, 0, sizeof (sl->q_buf)); - buf[0] = STLINK_DEBUG_COMMAND; - buf[1] = STLINK_DEBUG_EXIT; + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_EXIT; - size = send_only(slu, buf, 16); + size = send_only(slu, 1, cmd, slu->cmd_len); if (size == -1) { printf("[!] send_only\n"); return; @@ -393,21 +420,17 @@ void _stlink_usb_exit_debug_mode(stlink_t *sl) { void _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; ssize_t size; + int i = fill_command(sl, SG_DXFER_FROM_DEV, len); - /* assume len < sizeof(sl->q_buf) */ + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_READMEM_32BIT; + write_uint32(&cmd[i], addr); + write_uint16(&cmd[i + 4], len); - memset(buf, 0, sizeof (sl->q_buf)); - buf[0] = STLINK_DEBUG_COMMAND; - buf[1] = STLINK_DEBUG_READMEM_32BIT; - write_uint32(buf + 2, addr); - /* windows usb logs show only one byte is used for length ... */ - // Presumably, this is because usb transfers can't be 16 bits worth of bytes long... - assert (len < 256); - buf[6] = (uint8_t) len; - - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, len); if (size == -1) { printf("[!] send_recv\n"); return; @@ -418,20 +441,17 @@ void _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { stlink_print_data(sl); } - -#if 1 /* stlinkv1 */ - void _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) { struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; - unsigned char* const cmd_buf = sl->c_buf; + unsigned char* const cmd = sl->c_buf; + unsigned char* const data = sl->q_buf; ssize_t size; - int i; + uint32_t rep_len = 84; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - memset(cmd_buf, 0, STLINK_CMD_SIZE); - cmd_buf[0] = STLINK_DEBUG_COMMAND; - cmd_buf[1] = STLINK_DEBUG_READALLREGS; - size = send_recv(slu, cmd_buf, STLINK_CMD_SIZE, buf, 84); + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_READALLREGS; + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); return; @@ -455,53 +475,19 @@ void _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) { DD(sl, "rw2 = 0x%08x\n", read_uint32(sl->q_buf, 80)); } -#else /* stlinkv2 */ - -static void _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; - unsigned char* const cmd_buf = sl->c_buf; - ssize_t size; - int i; - -#define STLINK_JTAG_COMMAND 0xf2 -#define STLINK_JTAG_READALLREGS2 0x3a - memset(cmd_buf, 0, STLINK_CMD_SIZE); - cmd_buf[0] = STLINK_JTAG_COMMAND; - cmd_buf[1] = STLINK_JTAG_READALLREGS2; - size = send_recv(slu, cmd_buf, STLINK_CMD_SIZE, buf, 84); - - if (size == -1) { - printf("[!] send_recv\n"); - return; - } - - sl->q_len = (size_t) size; - - for(i=0; i<16; i++) - regp->r[i]= read_uint32(sl->q_buf, i*4); - - regp->xpsr = read_uint32(sl->q_buf, 64); - regp->main_sp = read_uint32(sl->q_buf, 68); - regp->process_sp = read_uint32(sl->q_buf, 72); - regp->rw = read_uint32(sl->q_buf, 76); - regp->rw2 = read_uint32(sl->q_buf, 80); -} - -#endif /* stlinkv1 */ - void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; - unsigned char* const cmd_buf = sl->c_buf; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; ssize_t size; uint32_t r; + uint32_t rep_len = 4; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - memset(cmd_buf, 0, STLINK_CMD_SIZE); - cmd_buf[0] = STLINK_DEBUG_COMMAND; - cmd_buf[1] = STLINK_DEBUG_READREG; - cmd_buf[2] = (uint8_t) r_idx; - size = send_recv(slu, cmd_buf, STLINK_CMD_SIZE, buf, 4); + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_READREG; + cmd[i++] = (uint8_t) r_idx; + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); return; @@ -522,31 +508,29 @@ void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { regp->process_sp = r; break; case 19: - regp->rw = r; //XXX ?(primask, basemask etc.) + regp->rw = r; /* XXX ?(primask, basemask etc.) */ break; case 20: - regp->rw2 = r; //XXX ?(primask, basemask etc.) + regp->rw2 = r; /* XXX ?(primask, basemask etc.) */ break; default: regp->r[r_idx] = r; } } - -#if 1 /* stlinkv1 */ - void _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; - unsigned char *cmd_buf = sl->c_buf; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; ssize_t size; - - memset(cmd_buf, 0, STLINK_CMD_SIZE); - cmd_buf[0] = STLINK_DEBUG_COMMAND; - cmd_buf[1] = STLINK_DEBUG_WRITEREG; - cmd_buf[2] = idx; - write_uint32(cmd_buf + 3, reg); - size = send_recv(slu, cmd_buf, STLINK_CMD_SIZE, buf, 2); + uint32_t rep_len = 2; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_WRITEREG; + cmd[i++] = idx; + write_uint32(&cmd[i], reg); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); return; @@ -555,32 +539,6 @@ void _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { stlink_print_data(sl); } -#else /* stlinkv2 */ - -void _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const buf = sl->q_buf; - unsigned char *cmd_buf = sl->c_buf; - ssize_t size; - -#define STLINK_JTAG_WRITEREG2 0x34 - memset(cmd_buf, 0, STLINK_CMD_SIZE); - cmd_buf[0] = STLINK_JTAG_COMMAND; - cmd_buf[1] = STLINK_JTAG_WRITEREG2; - cmd_buf[2] = idx; - write_uint32(cmd_buf + 3, reg); - size = send_recv(slu, cmd_buf, STLINK_CMD_SIZE, buf, 2); - if (size == -1) { - printf("[!] send_recv\n"); - return; - } - sl->q_len = (size_t) size; - stlink_print_data(sl); -} - -#endif /* stlinkv1 */ - - stlink_backend_t _stlink_usb_backend = { _stlink_usb_close, _stlink_usb_exit_debug_mode, @@ -604,38 +562,48 @@ stlink_backend_t _stlink_usb_backend = { }; -stlink_t* stlink_open_usb(const char *dev_name, const int verbose) { +stlink_t* stlink_open_usb(const int verbose) { stlink_t* sl = NULL; struct stlink_libusb* slu = NULL; - - /* unused */ - dev_name = dev_name; + int error = -1; + libusb_device** devs = NULL; + libusb_device* dev; + ssize_t i; + ssize_t count; + int config; + char *iSerial = NULL; sl = malloc(sizeof (stlink_t)); slu = malloc(sizeof (struct stlink_libusb)); if (sl == NULL) goto on_error; if (slu == NULL) goto on_error; + memset(sl, 0, sizeof (stlink_t)); + memset(slu, 0, sizeof (struct stlink_libusb)); sl->verbose = verbose; + sl->backend = &_stlink_usb_backend; + sl->backend_data = slu; - if (slu->libusb_ctx != NULL) { - fprintf(stderr, "reopening with an existing context? undefined behaviour!\n"); - goto on_error; - } else { - if (libusb_init(&(slu->libusb_ctx))) { - fprintf(stderr, "failed to init libusb context, wrong version of libraries?\n"); - goto on_error; - } - } + sl->core_stat = STLINK_CORE_STAT_UNKNOWN; - int error = -1; + /* flash memory settings */ + sl->flash_base = STM32_FLASH_BASE; + sl->flash_size = STM32_FLASH_SIZE; + sl->flash_pgsz = STM32_FLASH_PGSZ; - libusb_device** devs = NULL; - libusb_device* dev; - ssize_t i; - ssize_t count; - int config; + /* system memory */ + sl->sys_base = STM32_SYSTEM_BASE; + sl->sys_size = STM32_SYSTEM_SIZE; + + /* sram memory settings */ + sl->sram_base = STM32_SRAM_BASE; + sl->sram_size = STM32L_SRAM_SIZE; + if (libusb_init(&(slu->libusb_ctx))) { + fprintf(stderr, "failed to init libusb context, wrong version of libraries?\n"); + goto on_error; + } + count = libusb_get_device_list(slu->libusb_ctx, &devs); if (count < 0) { printf("libusb_get_device_list\n"); @@ -644,14 +612,47 @@ stlink_t* stlink_open_usb(const char *dev_name, const int verbose) { for (i = 0; i < count; ++i) { dev = devs[i]; - if (is_stlink_device(dev)) break; + slu->protocoll = is_stlink_device(dev, 0); + if (slu->protocoll > 0) break; } - if (i == count) return NULL; + if (i == count) goto on_libusb_error; if (libusb_open(dev, &(slu->usb_handle))) { printf("libusb_open()\n"); goto on_libusb_error; } + + if (iSerial) { + unsigned char serial[256]; + struct libusb_device_descriptor desc; + int r; + + r = libusb_get_device_descriptor(dev, &desc); + if (r<0) { + printf("Can't get descriptor to match Iserial\n"); + goto on_libusb_error; + } + r = libusb_get_string_descriptor_ascii + (slu->usb_handle, desc.iSerialNumber, serial, 256); + if (r<0) { + printf("Can't get Serialnumber to match Iserial\n"); + goto on_libusb_error; + } + if (strcmp((char*)serial, iSerial)) { + printf("Mismatch in serial numbers, dev %s vs given %s\n", + serial, iSerial); + goto on_libusb_error; + } + } + + if (libusb_kernel_driver_active(slu->usb_handle, 0) == 1) { + int r; + + r = libusb_detach_kernel_driver(slu->usb_handle, 0); + if (r<0) + printf("libusb_detach_kernel_driver(() error %s\n", strerror(-r)); + goto on_libusb_error; + } if (libusb_get_configuration(slu->usb_handle, &config)) { /* this may fail for a previous configured device */ @@ -688,15 +689,20 @@ stlink_t* stlink_open_usb(const char *dev_name, const int verbose) { slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; - /* libusb_reset_device(slu->usb_handle); */ + slu->sg_transfer_idx = 0; + slu->cmd_len = (slu->protocoll == 1)? STLINK_SG_SIZE: STLINK_CMD_SIZE; /* success */ + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { + printf("-- exit_dfu_mode\n"); + stlink_exit_dfu_mode(sl); + } + stlink_version(sl); error = 0; on_libusb_error: if (devs != NULL) { libusb_free_device_list(devs, 1); - fprintf(stderr, "freed libusb device list\n"); } if (error == -1) { @@ -704,8 +710,6 @@ on_libusb_error: return NULL; } - sl->backend = &_stlink_usb_backend; - sl->backend_data = slu; /* success */ return sl; diff --git a/src/stlink-usb.h b/src/stlink-usb.h index 4ed655b..c632a8c 100644 --- a/src/stlink-usb.h +++ b/src/stlink-usb.h @@ -15,6 +15,7 @@ extern "C" { #include #include "stlink-common.h" +#define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 #if defined(CONFIG_USE_LIBUSB) @@ -25,6 +26,9 @@ extern "C" { struct libusb_transfer* rep_trans; unsigned int ep_req; unsigned int ep_rep; + int protocoll; + unsigned int sg_transfer_idx; + unsigned int cmd_len; }; #else #error "it's all bad!" @@ -32,7 +36,7 @@ extern "C" { #endif - stlink_t* stlink_open_usb(const char *dev_name, const int verbose); + stlink_t* stlink_open_usb(const int verbose); #ifdef __cplusplus diff --git a/src/test_sg.c b/src/test_sg.c index 137eca4..34fbe54 100644 --- a/src/test_sg.c +++ b/src/test_sg.c @@ -6,8 +6,10 @@ #include #include +#if CONFIG_USE_LIBSG #include #include +#endif #include "stlink-common.h" int main(int argc, char *argv[]) { @@ -210,4 +212,4 @@ int main(int argc, char *argv[]) { //fflush(stderr); fflush(stdout); return EXIT_SUCCESS; -} \ No newline at end of file +} diff --git a/src/test_usb.c b/src/test_usb.c index bd81ec1..343e355 100644 --- a/src/test_usb.c +++ b/src/test_usb.c @@ -10,7 +10,7 @@ int main(int ac, char** av) { ac = ac; av = av; - sl = stlink_open_usb(NULL, 10); + sl = stlink_open_usb(10); if (sl != NULL) { printf("-- version\n"); stlink_version(sl); -- 2.30.2